博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Thinking in java中关于Exception的一道面试题.
阅读量:6980 次
发布时间:2019-06-27

本文共 2233 字,大约阅读时间需要 7 分钟。

今天看到Thinking in Java中一个关于Exception的例子:

最后看到有一篇总结的比较好的文章, 这里拿来记录下, 文章地址是:http://blog.csdn.net/salerzhang/article/details/46581457  感谢原作者.

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 }

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

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

Caught AnnoyanceCaught SneezeHello World!

相信第一行和第三行大家都没什么疑问了,关键是第二行,应该出来吗?是不是子类捕获了父类的异常呢?

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

catch ( Annoyance a )

这一句使用的是父类的引用,但实际上是子类的对象,这是java中多态的经典表现, 在Annoyance a中捕获的其实是Sneeze的异常。在

catch ( Sneeze s )

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

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

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 }

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

Hello World!Exception in thread "main" com.xq.exceptions.Annoyanceat com.xq.exceptions.Human.main(ExceptionTest.java:14)

可以看到,出了问题了,也就是说,父类throw出来的异常,子类并没有捕获到,继续往下证明:

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!

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

你可能感兴趣的文章
JavaScript—ES6关于Promise的用法(19)
查看>>
Google发布机器学习平台Tensorflow游乐场~带你玩神经网络(转载)
查看>>
centos6.0下安装FTP客户端命令
查看>>
SAN存储方式之falconstor实施方案(2)
查看>>
Bokeh快速入门(1)
查看>>
读取本机的Java运行环境和相关配置文件的内容
查看>>
Linux系统下的RZSZ(文件传输工具)
查看>>
第5章选择结构程序设计
查看>>
linux 下网络流量监控
查看>>
[CentOS6] Page allcation failure
查看>>
MagicLinux+MySQL5+PHP5+Apache2+phpMyAdmin
查看>>
服务器RAID磁盘坏道修复实战
查看>>
SOAP
查看>>
理解Windows中的路由表和默认网关
查看>>
MalformedInputException处理
查看>>
OPENAPI的测试用例编写方法
查看>>
事件通知(Event Notification)实践
查看>>
java json和object互换
查看>>
脚本语言程序员怎么学习程序设计?
查看>>
帮助电力,轻松实现运维管理
查看>>