明辉手游网中心:是一个免费提供流行视频软件教程、在线学习分享的学习平台!

Java编程思想读书笔记(10章中)

[摘要]三. 以finally进行清理  1. 如果某段代码不管是否发生异常都要执行,那可把它改入finally块中。   import java.sql.SQLException;   class TestException   public static void tSq...
三. 以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)中抛出的异常丢失了。