Java で try-catch-finally が入れ子になっているとき、内側の try で例外が発生した場合に外側の finally を通ることを確認してみた。
import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; import java.sql.SQLException; import h.Hoge2; public class Hoge { public static void main(String args[]) { Connection conn = null; try { Class.forName ("oracle.jdbc.driver.OracleDriver"); conn = DriverManager.getConnection ("jdbc:oracle:thin:@192.168.45.101:1521:orcl","scott","tiger"); Hoge2 h2 = new Hoge2(conn); h2.insert(); } catch (SQLException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { try { if (conn != null) { conn.close(); } } catch (SQLException e){ e.printStackTrace(); } System.out.println("finally at Hoge#main()"); } } }
- h/Hoge2.java
package h; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; import java.sql.SQLException; public class Hoge2 { private Connection conn = null; public Hoge2(Connection conn) { this.conn = conn; } public void insert() { Statement stmt = null; try { stmt = conn.createStatement(); int resultCount = stmt.executeUpdate ("insert into emp(id, name) values('001','scott')"); conn.commit(); if (resultCount == 1) { System.out.println("A row was inserted successfully."); } else { System.out.println("Failed to insert a row."); } } catch(SQLException e) { e.printStackTrace(); } finally { try { if (stmt != null) { stmt.close(); } } catch(SQLException e) { e.printStackTrace(); } } System.out.println("finally at Hoge2#insert()"); } }
- コンパイルする。
$ $ find . -ls 1081255 0 drwxr-xr-x 6 yohei staff 204 4 4 22:03 . 1082543 0 drwxr-xr-x 3 yohei staff 102 4 4 22:03 ./h 1093667 8 -rw-r--r-- 1 yohei staff 1392 4 4 21:58 ./h/Hoge2.java 1093655 8 -rw-r--r-- 1 yohei staff 743 4 4 21:57 ./Hoge.java 1081926 3040 -rw-r--r-- 1 yohei staff 1555682 3 12 19:21 ./ojdbc14.jar $ javac h/Hoge2.java $ javac Hoge.java
- 実行してみる。
$ export CLASSPATH=.:$CLASSPATH:ojdbc14.jar $ java Hoge A row was inserted successfully. finally at Hoge2#insert() finally at Hoge#main()
- もう一回実行すると、一意制約違反で例外発生。ちゃんと Hoge#main() の finally を通っている。
$ java Hoge java.sql.SQLException: ORA-00001: unique constraint (SCOTT.SYS_C004424) violated at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331) at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288) at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:745) at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:210) at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:961) at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1190) at oracle.jdbc.driver.OracleStatement.executeUpdateInternal(OracleStatement.java:1657) at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:1626) at h.Hoge2.insert(Hoge2.java:18) at Hoge.main(Hoge.java:15) finally at Hoge2#insert() finally at Hoge#main()