三. 以finally进行清理
1. 如果某段代码不管是否发生异常都要执行,那可把它改入finally块中。
import java.sql.SQLException; class TestException{ public static void tSql() throws SQLException { System.out.println("Originating the exception in tSql()"); throw new SQLException("throw in tSql"); } public void f() throws SQLException{ try{ tSql(); } catch(SQLException ex){ System.out.println("catch SQLException in f()"); throw ex;//(1)
} finally{ System.out.println("finally in f()"); } } } public class Test{ public static void main(String[] args){ TestException te = new TestException(); try{ te.f(); } catch(SQLException ex){ System.out.println("catch te.f() SQLException in main"); } catch(Exception ex){ System.out.println("catch te.f() Exception in main"); } } } 运行结果为:
Originating the exception in tSql()
catch SQLException in f()
finally in f()
catch te.f() SQLException in main 虽然在代码(1)处重新抛出异常,但finally块中的代码仍然会被执行。
2. finally造成的异常遗失
如果在finally中执行的代码又产生异常,那么在上一层调用中所捕捉到的异常的起始抛出点会是finally所在的函数。
import java.sql.SQLException; class TestException{ public static void tSql1() throws SQLException { System.out.println("Originating the exception in tSql()"); throw new SQLException("throw in tSql1"); } public static void tSql2() throws SQLException { System.out.println("Originating the exception in tSql()"); throw new SQLException("throw in tSql2"); } public void f() throws SQLException{ try{ tSql1(); } catch(SQLException ex){ System.out.println("catch SQLException in f()"); throw ex;//(2)
} finally{ System.out.println("finally in f()"); //tSql2();(1)
} } } public class Test{ public static void main(String[] args){ TestException te = new TestException(); try{ te.f(); } catch(SQLException ex){ System.out.println("catch te.f() SQLException in main"); System.out.println("getMessage:" + ex.getMessage()); System.out.println("printStackTrace:"); ex.printStackTrace(); } } } 运行结果为:
Originating the exception in tSql()
catch SQLException in f()
finally in f()
catch te.f() SQLException in main getMessage:throw in tSql1 printStackTrace:
java.sql.SQLException: throw in tSql1 void TestException.tSql1()
Test.java:5 void TestException.f()
Test.java:13 void Test.main(java.lang.String[])
Test.java:29 从结果可以看出,在main()中能正确打印出所捕捉到的异常的起始抛出点。但如果去掉代码(1)的注释,结果将变为:
Originating the exception in tSql()
catch SQLException in f()
finally in f()
Originating the exception in tSql()
catch te.f() SQLException in main getMessage:throw in tSql2 printStackTrace:
java.sql.SQLException: throw in tSql2 void TestException.tSql2()
Test.java:9 void TestException.f()
Test.java:21 void Test.main(java.lang.String[])
Test.java:29 从结果可以看出,在main()中捕捉到的异常是finally中产生的异常,代码(2)中抛出的异常丢失了。
|