java异常捕获的一点感悟

转载于:https://blog.csdn.net/salerzhang/article/details/46581457


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

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

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

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

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

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

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

catch ( Annoyance a ) 

这一句使用的是父类的引用,但实际上是子类的对象,这是java中多态的经典表现。在

catch ( Sneeze s )
的时候当然可以捕获到自己抛出来的异常了。

为了证明,子类从本质上无法捕获父类的异常,我们继续做个试验:

  1. try {
  2. throw new Annoyance();
  3. } catch (Sneeze s) {
  4. System.out.println( "Caught Sneeze");
  5. return;
  6. } finally {
  7. System.out.println( "Hello World!");
  8. }


可以看到,抛出了父类的异常,使用子类catch,这时候可以通过编译,但运行时呢?

  1. Hello World!
  2. Exception in thread "main" com.xq.exceptions.Annoyance
  3. at com.xq.exceptions.Human.main(ExceptionTest.java: 14)
可以看到,出了问题了,也就是说,父类throw出来的异常,子类并没有捕获到,继续往下证明:

  1. try {
  2. throw new Annoyance();
  3. } catch (Sneeze s) {
  4. System.out.println( "Caught Sneeze");
  5. return;
  6. } catch (Exception e) {
  7. System.out.println( "Caught Exception");
  8. return;
  9. } finally {
  10. System.out.println( "Hello World!");
  11. }

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

Caught Exception
Hello World!

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




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

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

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

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

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

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

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

catch ( Annoyance a ) 

这一句使用的是父类的引用,但实际上是子类的对象,这是java中多态的经典表现。在

catch ( Sneeze s )
的时候当然可以捕获到自己抛出来的异常了。

为了证明,子类从本质上无法捕获父类的异常,我们继续做个试验:

  1. try {
  2. throw new Annoyance();
  3. } catch (Sneeze s) {
  4. System.out.println( "Caught Sneeze");
  5. return;
  6. } finally {
  7. System.out.println( "Hello World!");
  8. }


可以看到,抛出了父类的异常,使用子类catch,这时候可以通过编译,但运行时呢?

  1. Hello World!
  2. Exception in thread "main" com.xq.exceptions.Annoyance
  3. at com.xq.exceptions.Human.main(ExceptionTest.java: 14)
可以看到,出了问题了,也就是说,父类throw出来的异常,子类并没有捕获到,继续往下证明:

  1. try {
  2. throw new Annoyance();
  3. } catch (Sneeze s) {
  4. System.out.println( "Caught Sneeze");
  5. return;
  6. } catch (Exception e) {
  7. System.out.println( "Caught Exception");
  8. return;
  9. } finally {
  10. System.out.println( "Hello World!");
  11. }

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

Caught Exception
Hello World!

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



猜你喜欢

转载自blog.csdn.net/qq_28817739/article/details/80874844