Try with resources in Java

Keywords: SQL Java

This is the ninth article of Effective Java.

To illustrate the problem, I write an ugly code first:

    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();
                }
            }
            
        }
        
    }

The ugliness of this code comes from finally. For resource-based objects, close is necessary, and it is reasonable to write it in finally block. However, there are also problems. Even in the finally block, the close method still faces the problem of throwing an exception when it is called. So our code can only be written in such an ugly way.

In many cases, exceptions should be thrown. Based on this consideration, let's change the code as follows:

    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();
        }
    }

In this way, the code is much more beautiful, and the exception thrown will be caught by a higher level caller, which is also a good design. However, this code has something to change:

    private void doOtherThing(Connection connection) throws SQLException {
        String sql = "select 1";
        try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
            preparedStatement.executeQuery();
        }
    }

In this way, you don't need to write the finally block. At this time, the system will automatically help you close the resource object. Why? In fact, this is because these objects all implement the autoclosable interface:

public interface Connection  extends Wrapper, AutoCloseable 

Java is also on its way to elegance.

I think Java is the best language in the world.

Posted by witty on Sun, 17 Nov 2019 09:04:49 -0800