Java把所有非正常情况分为两种:异常(Exception)和错误(Error),它们都继承Throwable父类。
Error错误,一般是指与虚拟机相关的问题,如系统崩溃、虚拟机错误,动态链接失败等,这种错误无法恢复,不可捕捉,将导致应用程序中断。
异常捕获时,先捕获小异常,再捕获大异常。即所有父类异常的catch块都应该排在子类异常catch块的后面,否则编译出错。
Java7以前,每个catch块只能捕获一种类型的异常;从Java7开始,可以捕获多中类型的异常。
(1)捕获多种类型的异常时,多种异常类型之间用竖线( | )隔开;
(2)捕获多种类型的异常时,异常变量有隐式的final修饰,因此不能对异常变量重新赋值。
捕获一种异常时,异常变量没有final修饰。
finally回收资源
不管try块中的代码是否出现异常,也不管那个catch块被执行,甚至在try和catch块中都使用了return语句,finally块总会被执行,除非在try块执行之前,被return或者在finally块之前调用了System.exit(1)语句退出虚拟机。
Demo1:
private static int test1() {
int i = 1;
try {
System.out.println("test1===========try...");
i = i+1;
return i;
} catch (Exception e) {
System.out.println("test1===========catch...");
} finally {
i++;
System.out.println("test1===========finally...");
System.out.println("test1===========i=" + i);
}
return i;
}
结论:finally代码块是在try代码块中的return语句执行之后,返回之前执行的。
Demo2:
@SuppressWarnings("finally")
private static int test2() {
int i = 1;
try {
System.out.println("test2===========try...");
return i += 1;
} catch (Exception e) {
System.out.println("test2===========catch...");
} finally {
i++;
System.out.println("test2===========finally...");
System.out.println("test2===========i=" + i);
return i;
}
}
结论:finally代码块中的return语句会覆盖try代码块中的return语句。
Demo3:
private static HashMap<String, String> test3() {
HashMap<String, String> map = new HashMap<String, String>();
map.put("key", "init");
try {
System.out.println("test3===========try...");
map.put("key", "try");
return map;
} catch (Exception e) {
System.out.println("test3===========catch...");
map.put("key", "catch");
} finally {
System.out.println("test3===========finally...");
map.put("key", "finally");
map=null;
}
return map;
}
对比Demo1和Demo3发现
如果finally语句中没有用return语句覆盖返回值,那么原来的返回值可能因为finally块里的修改而改变也可能不变。传值类型的返回值:不变;传址类型的返回值:会变。传值:8种基本数据类型及其包装类,字符常量。传址:数组和对象。
在Demo3中的finally块中我把map设置为null,为什么返回的值还是“test3={key=finally}”?
程序在执行到try{}语句中的return方法后,就会先返回相应的值,并把相应的值(map的引用地址值)存储在一个临时栈中去保存这个结果。在finally执行完后,方法全部执行完,这时会再次调用return方法,这时不在是返回值,而是告诉主调程序,被调程序已经执行完了,可以接着去执行主程序中的其它方法了。此时返回的值还是原来保存在临时栈中的值,所以map的不是null。
Demo4:
try块,finally块没有返回值的时候,代码顺序执行