序言
Java 的异常捕捉通常使用 try-catch 捕捉或者 throws 抛出处理。这篇文章就来探讨下 try-catch 的一些事。
try-catch 和 throws 异常处理
try-catch 和 throws 处理异常一般按照,如果底层异常就往上层抛出(throws) ,上层异常 try-catch 处理。(PS:这里底层上层是面向对象的编程语言的封装程度相对而言)
try-catch 和 try-catch-finally
- 两者最大的区别就是,是否与 finally 结合使用。其实 finally 存在的意义就是为了防止异常中断 try 代码块中程序,直接跳到异常处理之后,相关资源(如 IO、线程等等)没有释放,导致资源浪费或者内存泄漏等等。
- 通常是在 finally 中关闭相关资源。
后面就来看下 try-catch-finally 的执行顺序
try-catch-finally 执行顺序
举个例子(如下):
public static void main(String[] args) {
FileInputStream input = new FileInputStream("D:\\File\\Demo.txt");
try {
// 1
// some code that might throw exceptions
// 2
} catch(IOException e){
// 3
// show error message
// 4
} finally {
// 5
input.close();
}
// 6
}
在上面的这段代码会有3中执行顺序:
- try 中代码没有异常抛出
执行顺序是先执行 try 中的语句,然后执行 finally 中语句,最后执行后续语句。执行顺序就是:1 --> 2 --> 5 --> 6
- try 中代码异常,在 catch 中捕获
执行顺序是先执行 try 中代码,此时 try 中代码异常抛出,程序跳转到 catch 中,然后执行 finally 中的语句,最后执行后续语句。
执行顺序是:1 --> 3 --> 4 --> 5 --> 6
注意:如果此时 catch 块中抛出一个异常,程序会自动跳到 finally 中。
执行顺序为:1 --> 3 --> 5 -->6
- try 中代码异常,catch 中无法捕获该异常
举个栗子,抛出异常为IoException, catch 中设定异常为 SQLException,程序将执行 try 中代码直到异常抛出,最后直接执行 finally 和后续代码。
执行顺序为:1 --> 5 --> 6
最后
我们在使用 try-catch-finally 语句中,牢记其三种情况下的执行顺序,可以减少爬一些不必要的坑。
2019.09.01 更新
- 当 finally 中包含 return 会出现一些意想不到的情况。假如利用 return 语句从 try 中退出,再放发前,finally 中的语句会在返回前执行。如果 finally 中也有 return,那么前者的 return 会被覆盖原始返回值。例如,见下:
/**
* 该方法返回 r 的值
*/
public static int fun(int n) {
try {
int r = n * n;
return r;
} catch (Exception e) {
if( n == 2) {
return 0;
}
}
}
如果调用 fun(2) ,那么 try 中计算结果是 4 , 并执行 return 语句。然而,在方法真正返回之前,还要执行 finally 的语句,finally 中语句使得方法返回 0 , 这个返回值覆盖了原来的返回值 4。
人若无名,专心练剑!
####### 觉得文章还不错的童鞋,可以留下你的点赞和评论。