java异常处理机制中的try -catch
try的用法:
- try后面可以写 一个或多个catch,0个或1个finally
- 也可以只写1个finally
- try不能单独使用
语法:
try{
代码片段
}catch(XXException e){
// 异常捕获后,自定义处理手段
e.printStackTrace()
}finall{
必定执行的代码
}
当JVM执行代码遇到异常时,会实例化该异常的一个实例,然后设置好代码执行的过程,并将该异常抛出。如果抛出异常的代码所在方法没有处理异常的能力,异常会抛到当前方法之外,由调用当前方法的代码片段去处理。
try代码片段中出错的代码之后的内容都不会执行,catch可以定义多个,针对不同的异常有不同的处理手段时,可以分别捕获这些异常,但是小异常在前,大异常在后。
finally块是异常捕获机制中的最后一块
- finally可以直接跟在try后面,或最后一个catch之后。
- finally中的代码都必定会执行
- 将IO中的关闭流操作放在finally中
- 就算catch中的return之后,finally也要运行完在return。
下面的代码执行后结果为1
大致流程是:首先:i 在try中i++后,i的值是1,紧接着抛出异常,执行catch中的代码;接着:执行输出catch语句,和第一次执行catch块中return i;(这里就已经将返回值i的值存起来了);最后:再执行finally中的i++,这时i=2;完了:第二次执行catch中的 return i; 这时返回的i是第一次执行时i的值 =1;
【相当于return i; 执行了两次。但是最后的结果是第一次返回值。】
如果在finally代码块中也添加一个return i;那么就不会第二次执行catch中的返回。
public static void main(String[] args) {
// 结果1
System.out.println(method());
}
public static int method() {
int i = 0;
try {
i++;
throw new NullPointerException();
} catch(Exception e) {
System.out.println("catch");
return i;
} finally {
System.out.println("finally");
i++;
}
}
JDK1.7后:将需要关闭资源的对象放在try后面的括号内,可以实现自动关闭
try(FileInputStream fis = new FileInputStream(file)){
代码块
}catch(XXException){
e.printStackTrace();
}
try() ->实现了AutoCloseable接口的可以定义在这,该特性是编译器认可,最终编译器还是会将代码改为在finally中关闭该流。
使用当前类测试异常的抛出
当不满足业务逻辑要求时,可以主动抛出异常
当一个方法中使用throw 抛出一个异常时,就应当在当前方法上使用throws声明该异常的抛出,通知调用者在调用当前方法时要处理异常(RuntimeException 除外)否则编译不通过。
当调用一个含有throws声明异常抛出的方法时,编译器要求必须处理这个异常,而处理方式有两种:
- 使用 try - catch处理异常
- 在当前方法上也thorws将异常抛出
派生类在继承超类时会重写其方法,那么在重写超类中含有throws声明异常抛出的方法时,对throws的重写规则:
- 重写所有异常
- 可以不再抛出任何异常
- 可以仅抛出父类方法抛出的部分异常
- 可以抛出父类方法抛出异常的子类型异常
- 不允许抛出额外异常
- 不允许抛出父类方法抛出异常的父类型异常。