为什么try-with-resource优于try-catch-finally
一、Effective Java 学习心得
1、学习了Java中的终结方法,建议是在日常开发中不要使用终结方法。
2、了解了try-with-resource语法糖(在jdk1.7引入)它让我们关闭资源不用嵌套在一层层的finally块中,比try-catch-finally靠谱(可能会产生异常屏蔽)。要使用try-with-resource的资源,必须先实现AutoCloseable接口,其中包含了单个返回void的close方法,Java类库与第三方类库中的许多类和接口,现在都实现或扩展了AutoCloseable接口,因此我们现在不必实现了(如:BufferedInputStream、BufferedOutputStream)。所以在考虑关闭资源的时候,try-with-resource是最优先的。
题外话: 当finally有return时,会直接返回。不会再去返回try或者catch中的返回值,而finally没有return时,try和catch 的return语句并不会马上执行,而是执行完finally代码块之后再返回try和catch里面的值。
异常屏蔽:异常屏蔽可以看下面的例子
public class Connection implements AutoCloseable {
public void sendData() throws Exception {
throw new Exception("send data");
}
@Override
public void close() throws Exception {
throw new MyException("close");
}
}
public class TryWithResource {
public static void main(String[] args) {
try {
test();
}
catch (Exception e) {
e.printStackTrace();
}
}
private static void test() throws Exception {
Connection conn = null;
try {
conn = new Connection();
conn.sendData();
} finally {
if (conn != null) {
conn.close();
}
}
}
}
控制台输出:
basic.exception.MyException: close
at basic.exception.Connection.close(Connection.java:10)
at basic.exception.TryWithResource.test(TryWithResource.java:82)
at basic.exception.TryWithResource.main(TryWithResource.java:7)
......
问题来了,由于我们一次只能抛出一个异常,所以在最上层看到的是最后一个抛出的异常——也就是 close 方法抛出的 MyException ,而 sendData 抛出的 Exception 被忽略了。这就是所谓的异常屏蔽。由于异常信息的丢失,异常屏蔽可能会导致某些bug变得极其难以发现,程序员们不得不加班加点地找bug。而使用try-with-resource就可以避免异常屏蔽。