这是《Effective Java》的第九条。
为了说明问题,我先写一段难看的代码:
private void doSomething(Connection connection) {
String sql = "select 1";
PreparedStatement preparedStatement = null;
try {
preparedStatement = connection.prepareStatement(sql);
preparedStatement.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
这段代码的丑陋就来源于finally,对于资源型的对象,close是必要的,而且写在finally块里是合情合理的。不过问题也随之而来,即便是在finally块中,close方法在调用的时候仍然面临着抛出异常的问题。于是我们的代码就只能妥协的写成如此丑陋的样子了。
很多时候其实异常是应该抛出的,基于这个考虑,我们把代码改造一下:
private void doSomething(Connection connection) throws SQLException {
String sql = "select 1";
PreparedStatement preparedStatement = null;
try {
preparedStatement = connection.prepareStatement(sql);
preparedStatement.executeQuery();
} finally {
connection.close();
preparedStatement.close();
}
}
这样代码就优美多了,而且抛出的异常会被更高一级的调用者捕获,这也是一种优良的设计。不过这段代码还是有可以更改的地方:
private void doOtherThing(Connection connection) throws SQLException {
String sql = "select 1";
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
preparedStatement.executeQuery();
}
}
这样连finally块都可以不需要写了,这个时候系统会自动的帮助你关闭资源对象,这是为什么呢?其实这是因为这些对象都实现了AutoCloseable接口:
public interface Connection extends Wrapper, AutoCloseable
Java也在向优雅的路上不断行进着。
我认为Java是世界上最好的语言。
网友评论