Previous Next |
Finally for ClosureIn the try-catch-finally triad, is the finally clause is often neglected. This clause allows you to write code that will run regardless of the outcome of the method. Whether the code within a try block throws an exception or not, code in a finally block will be executed by the compiler. The JDBC program in Example 5-6 shows how finally is used. Example 5-6. Closing database resources with finallypackage oracle.hcj.finalstory; public class FinallyForClosure { public int getValue(final Connection conn, final String sql) throws SQLException { int result = 0; Statement stmt = null; ResultSet rs = null; try { stmt = conn.createStatement( ); rs = stmt.executeQuery(sql); if (rs.next( )) { result = rs.getInt(1); } } catch (final SQLException ex) { throw ex; } finally { if (rs != null) { rs.close( ); } if (stmt != null) { stmt.close( ); } } return result; } } In this code, even if a SQLException is thrown, the method will attempt to close the ResultSet and Statement and thus release the resources they were consuming. In this manner, you can ensure that the database resources are closed no matter what happens. It is good practice to use finally blocks whenever you seize external resources inside of a try block. Although there is nothing technically wrong with the code in Example 5-6, you can make it even better. To understand how, consider the catch clause: } catch (final SQLException ex) { throw ex; } finally { The catch clause is this example is superfluous. To use a finally block, you do not have to catch any thrown exceptions; you can merely ignore them and let them be thrown by the method. When you reconsider the getValue( ) method, it becomes obvious that not catching the exceptions is a good idea. The getValue( ) method may throw a SQLException during the course of the method. Whatever happens, you need to close the database resources used in the call to prevent a resource leak. However, the attempted closure of these resources could generate SQLException instances as well. For this reason, you must declare that the method throws SQLException. The classic solution to this problem is to catch the exception from the try block and rethrow it, as shown in Example 5-6. However, a better approach is to use the finally block without catching the exceptions at all: package oracle.hcj.finalstory; public class FinallyForClosure { public int getValue2(final Connection conn, final String sql) throws SQLException { int result = 0; Statement stmt = null; ResultSet rs = null; try { stmt = conn.createStatement( ); rs = stmt.executeQuery(sql); if (rs.next( )) { result = rs.getInt(1); } } finally { if (rs != null) { rs.close( ); } if (stmt != null) { stmt.close( ); } } return result; } } Because this try block contains a finally block but no catch block, any exceptions thrown in the code will be merrily shot out of the method call, and the finally block will still be executed. This results in a much cleaner piece of code. |
Previous Next |