Java Part 1: Finally

2016-11-05  本文已影响15人  石头狮子

翻译自: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

上一篇下一篇

猜你喜欢

热点阅读