• java异常捕获的一点感悟


    1. class Annoyance extends Exception {}  
    2. class Sneeze extends Annoyance {}  
    3.   
    4. class Human {  
    5.   
    6.     public static void main(String[] args)   
    7.         throws Exception {  
    8.         try {  
    9.             try {  
    10.                 throw new Sneeze();  
    11.             }   
    12.             catch ( Annoyance a ) {  
    13.                 System.out.println("Caught Annoyance");  
    14.                 throw a;  
    15.             }  
    16.         }   
    17.         catch ( Sneeze s ) {  
    18.             System.out.println("Caught Sneeze");  
    19.             return ;  
    20.         }  
    21.         finally {  
    22.             System.out.println("Hello World!");  
    23.         }  
    24.     }  
    25. }  

    今天看到这么一段代码,请问输出的内容是什么?

    先别给出答案,思考一下平时我们写代码的过程中,异常捕获的过程和顺序,比如有这么一段代码:

    1. try {  
    2.             throw new FileNotFoundException();  
    3.         } catch (IOException e) {  
    4.   
    5.         }
    6. 我们经常能看到这样的代码,也就是使用父类能够捕获子类的异常,当然所有的异常都是继承Exception的,那么为什么不用Exception替换所有具体的异常类呢?这个是要考虑到我们对代码中预期异常的掌握,也就是某些代码会产生什么样的异常,程序员应当心中有数,如果全都用Exception的引用来接收,大家都是稀里糊涂的,如何进行处理也会变得难以着手。但如果在Catch代码块中不打算做任何处理,仅捕获而已,那么这时使用Exception也没什么关系,但正是生产环境下,这样的情况应该不允许存在的,这个看JDK的源码就知道了,捕获异常以后一定要给出提示信息的。

      以上的代码证明了,我们可以用父类的引用接受子类的异常对象,那么问题来了,最上面的代码执行结果是什么呢?答案是:

      1. Caught Annoyance  
      2. Caught Sneeze  
      3. Hello World!
      4. 相信第一行和第三行大家都没什么疑问了,关键是第二行,应该出来吗?是不是子类捕获了父类的异常呢?

        经过断点的加入,我们发现,尽管

        1. catch ( Annoyance a )   

        这一句使用的是父类的引用,但实际上是子类的对象,这是Java中多态的经典表现。在catch ( Sneeze s )  

        的时候当然可以捕获到自己抛出来的异常了。

      5. 为了证明,子类从本质上无法捕获父类的异常,我们继续做个试验:
        1. try {  
        2.   
        3.             throw new Annoyance();  
        4.         } catch (Sneeze s) {  
        5.             System.out.println("Caught Sneeze");  
        6.             return;  
        7.         } finally {  
        8.             System.out.println("Hello World!");  
        9.         } 
        10. 可以看到,抛出了父类的异常,使用子类catch,这时候可以通过编译,但运行时呢?
          [java] view plain copy
           
          1. Hello World!  
          2. Exception in thread "main" com.xq.exceptions.Annoyance  
          3.     at com.xq.exceptions.Human.main(ExceptionTest.java:14)  
          可以看到,出了问题了,也就是说,父类throw出来的异常,子类并没有捕获到,继续往下证明:
          [java] view plain copy
           
          1. try {  
          2.   
          3.             throw new Annoyance();  
          4.         } catch (Sneeze s) {  
          5.             System.out.println("Caught Sneeze");  
          6.             return;  
          7.         } catch (Exception e) {  
          8.             System.out.println("Caught Exception");  
          9.             return;  
          10.         } finally {  
          11.             System.out.println("Hello World!");  
          12.         }  

          既然子类捕获不了,那就使用Exception,可以看到结果如下:

          Caught Exception
          Hello World!

          看到这样,大家肯定都明白了,不用多说了!

        11. 感谢原作者的分享:http://blog.csdn.net/salerzhang/article/details/46581457
    情不知所起一往而深
  • 相关阅读:
    数据库之完整性约束
    数据库之数据类型
    数据库之表操作,数据操作
    mysql数据库之基本操作和存储引擎
    MySQL数据库之安装
    并发编程之socketserver模块
    python并发编程之IO模型
    [BZOJ 3207] 花神的嘲讽计划Ⅰ【Hash + 可持久化线段树】
    [BZOJ 1046] [HAOI2007] 上升序列 【DP】
    [BZOJ 1816] [Cqoi2010] 扑克牌 【二分答案】
  • 原文地址:https://www.cnblogs.com/xingbiaoblog/p/7079606.html
Copyright © 2020-2023  润新知