翻译自:finally
是否 finally 块总是被执行?
通常情况下 finally 块总是会被执行,除非我们定义了一些不正常的代码。
try,catch 异常退出
try {
System.exit(1);
} finally {
System.out.println("Hello World.");
}
这个例子中的 finally 则不会被执行。官方指南中有段注解:
Note: If the JVM exits while the try or catch code is being executed, then the finally block may not execute.
也就是说,try 或 catch 中的代码不会引起 JVM 退出的前提下,finally 就会被执行。
无限循环
try {
while(true){
System.out.println("Hello");
}
}finally{
System.out.println("World");
}
会打印出 World 吗?通常不会,除非打印语句出现错误。
线程
官方指南中的另一段注解:
...if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.
线程控制着程序执行流,而且也可以被中断。如果在执行 try 或 catch 时线程停止工作,那么 finally 就不会被执行。
Rule 1. Finally 总是执行的,除非程序或者线程被中断。
Finally 中的 return(Finally 何时执行?)
看下这个例子:
intsomeFunc(){
try{
return 0;
}finally{
return 1;
}
}
这个例子的结果很明显是 1。因为正常情况下 finally 总会返回。
intsomeFunc(){
try {
throw new RuntimeException();
}finally{
return1;
}
}
这个例子的结果也是 1,但是会有一个问题,异常丢失了。
这个问题就是众所周知的exception swallowing。是个非常危险的问题,因为客户端的代码想要得到异常或者值,但是只会得到值。
String deposit(intamount) throws DAOException{
try{
returndao.deposit(amount);
}finally{
return"OK";
}
}
这段代码中的逻辑是 finally 中包含默认值,方法抛出 DAOException
异常。客户端代码负责处理这个异常。
但是,只有编译器强制你处理这个异常。DAOException
永远不会抛出。并且 "OK" 则总会被返回。
Rule 2. 永远不要在 finally
中使用 return
。