20145312 《Java程序设计》第五周学习总结
2016-04-03 23:06
423 查看
20145312 《Java程序设计》第五周学习总结
学习笔记
Chapter8 异常处理
8.1语法与继承架构
1.Java中的错误以对象方式呈现,只要捕捉包装错误的对象,就可以针对该错误进行处理。8.1.1 使用try、catch
1.求平均值为例。
代码如下:
import java.util.Scanner; public class Average { public static void main(String[] args){ Scanner console=new Scanner(System.in); double sum=0; int count=0; while (true){ int number=console.nextInt() ; if(number==0){ break; } sum+=number; count++; } System.out.printf("平均%.2f%n",sum/count); } }
结果如下:
12 34 56 78 0 平均45.00
2.如果输入错误,会被打包成对象,可以尝试try()捕捉catch()代表错误的对象后做一些处理。
代码如下:
import java.util.* ; public class Average2 { public static void main(String[] args){ try{ Scanner console=new Scanner(System.in); double sum=0; int count=0; while (true) { int number = console.nextInt(); if (number == 0) { break; } sum += number; count++; } System.out.printf("平均%.2f%n",sum/count); }catch (InputMismatchException ex){ System.out.println("必须输入整数"); } } } /* JVM尝试执行try区块的代码,如果有错,执行流程跳过错误发生点,然后比较catch区块中声明的类型,是否符合错误对象类型,如果是就执行catch区块。 */
结果如下:
12 34 5o 必须输入整数
3.有时错误可以在捕捉处理之后,尝试恢复程序。
代码如下:
import java.util.*; public class Average3 { public static void main(String[] args){ Scanner console=new Scanner(System.in); double sum=0; int count=0; while (true) { try { int number = console.nextInt(); if (number == 0) { break; } sum += number; count++; } catch (InputMismatchException ex) { System.out.printf("略过非整数输入:%s%n", console.next()); } } System.out.printf("平均%.2f%n",sum/count); } } /* 如果nextInt()发生了InputMismatchException错误,流程跳至catch区块执行,并继续执行循环流程。 */
结果如下:
12 34 56 7o 略过非整数输入:7o 0 平均34.00
8.1.2 异常继承架构
1.错误会被包装成对象,且可抛出。
2.设计错误对象继承自java.lang.Throwable类,Throwable定义了取得错误信息、堆栈追踪等方法,它有两个子类:java.lang.Errow与java.lang.Exception。
代码如下:
import java.util.Scanner; public class Average4 { public static void main(String[] args){ double sum=0; int count=0; while (true) { int number = nextInt(); if (number == 0) { break; } sum += number; count++; } System.out.printf("平均%.2f%n",sum/count); } static Scanner console=new Scanner(System.in); static int nextInt() { String input = console.next(); while (!input.matches("\\d*"))//规则表示式,检查字符串中的字符是否是数字 { System.out.println("请输入数字"); input = console.next(); } return Integer.parseInt(input); } }
结果如下:
12 34 5o 请输入数字 78 0 平均41.33
8.1.3 要抓还是要抛
1.实际异常发生时,可使用try,catch处理当时环境可进行的异常处理,当时环境下无法决定如何处理的部分,可以抛出用调用方法的客户端处理。
代码如下:
import java.io.* ; import java.util.Scanner; public class FileUtil { public static String readFile(String name) throws FileNotFoundException{//声明方法中会抛出异常 StringBuilder text=new StringBuilder(); try{ Scanner console=new Scanner(new FileInputStream(name)); while(console.hasNext()){ text.append(console.nextLine()) .append('\n'); } }catch(FileNotFoundException ex){ ex.printStackTrace(); throw ex;//执行时抛出异常 } return text.toString(); } }
2.如果抛出的异常是非受检异常,表示你认为客户端调用方法的时机出错了,此时不用throw声明。
8.1.4 认识堆栈追踪
1.在多重方法调用下,异常发生点可能是在某个方法中,若想得知异常发生的根源,以及多重方法调用下异常的堆栈传播,可以利用异常对象自动收集的堆栈追踪来取的相关信息。
2.查看堆栈追踪最简单的方法,就是直接调用异常对象的printStackTrace()。
代码如下:
public class StackTraceDemo { public static void main(String[] args){ try{ c(); }catch(NullPointerException ex){ ex.printStackTrace() ; } } static void c(){ b(); } static void b(){ a(); } static String a(){ String text=null; return text.toUpperCase() ; } } /* c()方法调用b()方法,b()方法调用a()方法,而a()方法中会因text参考至null,而后试图调用toUpperCase引发NullPointerException。 */
结果如下:
java.lang.NullPointerException at TryCatch.StackTraceDemo.a(StackTraceDemo.java:22) at TryCatch.StackTraceDemo.b(StackTraceDemo.java:18) at TryCatch.StackTraceDemo.c(StackTraceDemo.java:15) at TryCatch.StackTraceDemo.main(StackTraceDemo.java:9) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
3.在使用throw重抛异常时,异常的追踪堆栈起点,仍是异常的发生根源,而不是重抛异常的地方。
代码如下:
public class StackTraceDemo2 { public static void main(String[] args){ try{ c(); }catch(NullPointerException ex){ ex.printStackTrace(); } } static void c(){ try{ b(); }catch(NullPointerException ex){ ex.printStackTrace(); throw ex; } } static void b(){ a(); } static String a(){ String text=null; return text.toUpperCase() ; } }
结果如下:
java.lang.NullPointerException at TryCatch.StackTraceDemo2.a(StackTraceDemo2.java:27) at TryCatch.StackTraceDemo2.b(StackTraceDemo2.java:23) at TryCatch.StackTraceDemo2.c(StackTraceDemo2.java:16) at TryCatch.StackTraceDemo2.main(StackTraceDemo2.java:9) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) java.lang.NullPointerException at TryCatch.StackTraceDemo2.a(StackTraceDemo2.java:27) at TryCatch.StackTraceDemo2.b(StackTraceDemo2.java:23) at TryCatch.StackTraceDemo2.c(StackTraceDemo2.java:16) at TryCatch.StackTraceDemo2.main(StackTraceDemo2.java:9) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
4.如果想要让异常堆栈起点为重抛异常的地方,可以的使用fillInStackTrace()方法,这个方法会重新装填异常堆栈,将起点设为重抛异常的地方,并返回Throwable对象。
代码如下:
public class StackTraceDemo3 { public static void main(String[] args){ try{ c(); }catch(NullPointerException ex){ ex.printStackTrace(); } } static void c(){ try{ b(); }catch(NullPointerException ex){ ex.printStackTrace(); Throwable t=ex.fillInStackTrace() ; throw (NullPointerException ) t; } } static void b(){ a(); } static String a(){ String text=null; return text.toUpperCase() ; } }
结果如下:
java.lang.NullPointerException at TryCatch.StackTraceDemo3.a(StackTraceDemo3.java:28) at TryCatch.StackTraceDemo3.b(StackTraceDemo3.java:24) at TryCatch.StackTraceDemo3.c(StackTraceDemo3.java:16) at TryCatch.StackTraceDemo3.main(StackTraceDemo3.java:9) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) java.lang.NullPointerException at TryCatch.StackTraceDemo3.c(StackTraceDemo3.java:19) at TryCatch.StackTraceDemo3.main(StackTraceDemo3.java:9) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
8.1.6关于assert
两种语法:
Assert Boolean_expresssion;
Assert Boolean_expresssion:detail_expression;
使用assert做关键词,默认执行时不启动断言检查。
3.何时使用断言:
断言客户端调用方法前,已经准备好某些前置条件(通常在private方法之中)。
断言客户端调用方法后,具有方法承诺的结果。
断言对象某个时间点下的状态。
使用断言取代批注。
断言程序流程中绝对不会执行到的程序代码部分。
8.2 异常与资源管理
8.2.1 使用finally1.try、catch语法可以搭配finally,执行关闭资源的动作。
代码如下:
import java.io.* ; import java.util.Scanner; public class FileUtil { public static String readFile(String name) throws FileNotFoundException{ StringBuilder text=new StringBuilder(); Scanner console=null; try{ console=new Scanner(new FileInputStream(name)); while(console.hasNext()){ text.append(console.nextLine()) .append('\n'); } }finally{ if(console !=null){ console.close(); } } return text.toString(); } }
2.如果程序撰写的流程中先return了,而且也有finally区块,那finally区块会先执行完后,再将值返回。
代码如下:
public class FinallyDemo { public static void main(String[] args){ System.out.println(test(true)); } static int test(boolean flag){ try{ if(flag){ return 1; } }finally{ System.out.println("finally..."); } return 0; } }
结果如下:
finally... 1
8.2.2 自动尝试关闭资源
1.JDK7之后,新增了尝试关闭资源(Try-With-Resources)语法。
代码如下:
import java.io.FileInputStream ; import java.io.FileNotFoundException ; import java.util.Scanner ; public class FileUtil2{ public static String readFile(String name) throws FileNotFoundException{ StringBuilder text=new StringBuilder(); try( Scanner console=new Scanner(new FileInputStream(name))){ while (console.hasNext() ){ text.append(console.nextLine()) .append('\n'); } } return text.toString(); } }
8.2.3 java.lang.AutoCloseable接口
AutoCloseable是JDK7新增的接口,仅定义了close()方法。
2.只要操作AutoCloseable接口,就可以套用至尝试关闭资源语法。
代码如下:
public class AutoCloseableDemo { public static void main(String[] args){ try(Resource res=new Resource()){ res.doSome(); }catch(Exception ex){ ex.printStackTrace() ; } } } class Resource implements AutoCloseable { void doSome(){ System.out.println("做一些事"); } @Override public void close() throws Exception { System.out.println("资源被关闭"); } }
结果如下:
做一些事 资源被关闭
2.尝试关闭资源语法可以关闭两个以上的对象资源,中间以分号隔开。
代码如下:
import static java.lang.System.out; public class AutoCloseableDemo2 { public static void main(String[] args){ try(ResourceSome some=new ResourceSome(); ResourceOther other=new ResourceOther()){ some.doSome(); other.doOther(); }catch(Exception ex){ ex.printStackTrace() ; } } } class ResourceSome implements AutoCloseable{ void doSome(){ System.out.println("做一些事"); } @Override public void close() throws Exception { System.out.println("资源some被关闭"); } } class ResourceOther implements AutoCloseable { void doOther() { System.out.println("做其他事"); } @Override public void close() throws Exception { System.out.println("资源other被关闭"); } }
结果如下:
做一些事 做其他事 资源other被关闭 资源some被关闭
Chapter 9 Collection与Map
9.1 使用Collection收集对象
9.1.1 认识Collection架构1.目的:针对收集对象的需求。
9.1.2 具有索引的List
1.List是一种Collection,作用是收集对象。
代码如下:
import java.util.* ; import java.util.ArrayList; import static java.lang.System.out; public class Guest { public static void main(String[] args){ List names=new ArrayList(); collectNameTo(names ); out.print("访客名单:"); printUpperCase(names); } static void collectNameTo(List names){ Scanner console=new Scanner(System.in); while(true){ out.print("访客名单:"); String name=console.nextLine(); if(name.equals("quit")){ break; } names.add(name); } } static void printUpperCase(List names){ for(int i=0;i<names.size();i++){ String name=(String)names.get(i); out.println(name.toUpperCase() ); } } }
结果如下:
访客名单:张三 访客名单:李四 访客名单:王二麻子 访客名单:quit 访客名单:张三 李四 王二麻子
2.ArrayList特性
有数组排序需求时,用ArrayList有较快的速度表现。
需要调整索引顺序时,用ArrayList有较差的表现。
ArrayList有个可指定容量的构造函数。
3.LinkedList特性
LinkedList在操作接口时,采用了Link结构。
代码如下:
public class SimpleLinkedList { private class Node{ Node(Object o){ this.o=o; } Object o; Node next; } private Node first; public void add(Object elem){ Node node=new Node(elem); if(first==null){ first=node; } else{ append(node); } } private void append(Node node){ Node last=first; while(last.next !=null){ last=last.next; } last.next=node; } public int size(){ int count=0; Node last=first; while(last !=null){ last=last.next; count++; } return count; } public Object get(int index){ checkSize(index); return findElemOf(index); } private void checkSize(int index) throws IndexOutOfBoundsException { int size=size(); if(index>=size){ throw new IndexOutOfBoundsException( String.format("Index:%d,Size:%d",index,size); } } private Object findElemOf(int index){ int count=0; Node last=first; while(count<index){ last=last.next; count++; } return last.elem; } }
9.1.3 内容不重复的Set
1.使用Set接口的操作对象,可以在手机对象过程中,遇到相同对象,可不重复收集。
代码如下:
import java.util.* ; public class WordCount { public static void main(String[] args){ Scanner console=new Scanner(System.in); System.out.println("请输入英文:"); Set words=tokenSet(console.nextLine()); System.out.printf("不重复单字有:%d个:%s%n",words.size(),words); } static Set tokenSet (String line){ String[] tokens=line.split(" "); return new HashSet(Arrays.asList(tokens)); } }
结果如下:
请输入英文: This is a dog that is a cat where is the student 不重复单字有:9个:[a, student, is, the, that, cat, This, where, dog]
2.若操作了hashCode()与equals()方法,则重复的Student不会被收集。
9.1.4 支持队列操作的Queue
1.作用:使用Queue接口的操作,收集对象时以队列方式,收集的对象加入至末尾端,取得对象时从前段。
2.建议使用offer()、poll()、peak()等方法。
代码如下:
import java.util.*; interface Request { void execute(); } public class RequestQueue { public static void main(String[] args) { Queue requests = new LinkedList(); offerRequestTo(requests); process(requests); } static void offerRequestTo(Queue requests) { for (int i = 1; i < 6; i++) { Request request = new Request() { public void execute() { System.out.printf("處理資料 %f%n", Math.random()); } }; requests.offer(request); } } static void process(Queue requests) { while(requests.peek() != null) { Request request = (Request) requests.poll(); request.execute(); } } }
9.1.5 使用泛型
1.作用:在设计API时可以指定类或方法支持泛型,而使用API的客户端在语法上会更为简洁,并得到编译时期检查。
代码如下:
import java.util.Arrays; public class ArrayList<E> { Object[] elems; private int next; public ArrayList(int capacity) { elems = new Object[capacity]; } public ArrayList() { this(16); } public void add(E e) { if(next == elems.length) { elems = Arrays.copyOf(elems, elems.length * 2); } elems[next++] = e; } public E get(int index) { return (E) elems[index]; } public int size() { return next; } }
9.1.6 简介Lambda表达式
1.相对于匿名类语法来说,Lambda表达式的语法省略了接口类型与方法名称,->左边是参数列,而右边是方法本体。
2.在Lambda表达式中使用区块时,如果方法必须有返回值,在区块中就必须使用return。
9.1.7 Interable与Iterator
1.interator()方法提升至新的java.util.Iterable父接口。
2.Collections的sort()方法要求被排序的对象必须java.lang.Comparable接口,这个接口有个compareTo()方法必须返回大于0、等于0或小于0的数。
9.1.8 Comparable与Comparator
1.Collections的sort()方法有另一个重载版本,java.util.Comparator接口的操作对象,如果使用这个版本,排序方式将根据Comparator的compare()定义来决定。
代码如下:
import java.util.*; class StringComparator implements Comparator<String> { @Override public int compare(String s1, String s2) { return -s1.compareTo(s2); } } public class Sort5 { public static void main(String[] args) { List<String> words = Arrays.asList("B", "X", "A", "M", "F", "W", "O"); Collections.sort(words, new StringComparator()); System.out.println(words); } }
9.2 键值对应的Map
9.2.1 常用Map操作类1.若要根据某个键来取得对应的值,可以事先利用java.util.Map接口的操作对象来建立键值对应数据,之后若要取得值,只要用对应的键就可以迅速取得。常用的Map操作类为java.util.HashMap与java.util.TreeMap,其继承自抽象类java.util.AbstractMap。
2.Map也支持泛型语法,如使用HashMap的范例。
代码如下:
import java.util.*; import static java.lang.System.out; public class Messages { public static void main(String[] args) { Map<String, String> messages = new HashMap<>(); messages.put("Justin", "Hello!Justin的訊息!"); messages.put("Monica", "給Monica的悄悄話!"); messages.put("Irene", "Irene的可愛貓喵喵叫!"); Scanner console = new Scanner(System.in); out.print("取得誰的訊息:"); String message = messages.get(console.nextLine()); out.println(message); out.println(messages); } }
如果使用TreeMap建立键值对应,则键的部分则会排序,条件是作为键的对象必须操作Comparable接口,或者是在创建TreeMap时指定操作Comparator接口的对象。
代码如下:
import java.util.*; public class Messages2 { public static void main(String[] args) { Map<String, String> messages = new TreeMap<>(); messages.put("Justin", "Hello!Justin的訊息!"); messages.put("Monica", "給Monica的悄悄話!"); messages.put("Irene", "Irene的可愛貓喵喵叫!"); System.out.println(messages); } }
9.2.2 访问Map键值
1.如果想取得Map中所有的键,可以调用Map的keySet()返回Set对象。由于键是不重复的,所以用Set操作返回是理所当然的做法,如果想取得Map中所有的值,则可以使用values()返回Collection对象。
代码如下:
import java.util.*; import static java.lang.System.out; public class MapKeyValue { public static void main(String[] args) { Map<String, String> map = new HashMap<>(); map.put("one", "一"); map.put("two", "二"); map.put("three", "三"); out.println("顯示鍵"); map.keySet().forEach(key -> out.println(key)); out.println("顯示值"); map.values().forEach(key -> out.println(key)); } }
教材学习中的问题和解决过程
1.问题1:在看书时不知道Error与Exception的区别。
解决过程:
Exception或其子类实例代表程序设计本身的错误,所以通常称错误处理为异常处理(Exception Handling)。
Error与其子类实例代表严重系统错误,如硬件层面错误、JVM错误或内存不足等问题,虽然也可以使用try、catch来处理Error对象,但并不建议,发生严重系统错误时,Java应用程序本身是无力回复的。
代码调试中的问题和解决过程
1.问题:在练习书P236的代码时,提示声明throw某些异常。
解决过程:
在仔细研读书后我看到书上提出了一些方法:
如果使用继承时,父类某个方法声明throws异常,子类重新定义该方法时可以:
不声明throws任何异常。
throws父类该方法中声明的某些异常。
throws父类该方法中声明异常的子类。
但是不可以:
throws父类方法中未声明的其他异常。
throws父类该方法中声明异常的父类。
其他(感悟、思考等,可选)
本周学习了第八、第九章,开始接触了各种类、接口、方法、行为,经常分不清楚,使用时分不清楚区别,所以我就边看书边打代码边总结知识点,这样能增加记忆,看到后面忘了前面的内容时就可以看知识点再记忆一遍。这周我学习Java的时间很集中,这样短时间内汲取了大量的知识,有了连贯性,认识的更全面。
托管代码截图
学习进度条
参考资料
Java学习笔记(第8版)《Java学习笔记(第8版)》学习指导
...
相关文章推荐
- 20145331《Java程序设计》第5周学习总结
- 20145222黄亚奇《Java程序设计》第5周学习总结
- 蛇形矩阵 java实现
- JavaSE学习笔记(2016.4.3)
- 第七章 springboot + retrofit
- 在Eclipse中导入项目的一般方法
- 关于java中==操作和.equals()函数的有趣讨论
- Jvm以及Jvm性能参数优化
- Java并发:await/wait 与sleep、yield间的区别
- servlet api简介(一)
- Spring源码分析篇01——Resource
- java classLoader体系结构使用详解
- java虚拟机自动内存管理机制
- 20145204《Java程序设计》第5周学习总结
- 20145321 《Java程序设计》第5周学习总结
- Java并发机制之Volatile关键字
- 20145225《Java程序设计》 第5周学习总结
- Step by Step into Spring (AOP)
- jdk8——Stream API
- 【jdk1.8】PriorityQueue源码分析