浅析java中的已检查(checked)异常和未检查(unchecked)异常

来源:互联网 发布:java工程师是做什么的 编辑:程序博客网 时间:2024/05/15 07:15

(图片来自网络,如果涉及侵权,请及时告知。谢谢!)

        作为一名java程序员,如果不懂异常,就绝对不是一名合格的程序员。异常看似简单,但是真正理解设计这种机制的背后用意,不是每一个人都能够做到的。小弟不才,试着分析一下,希望能为初学者带来一点启发。如果有错误,还请各路java大神及时指正。

1、什么是程序错误?

         程序在运行时出错了,怎么办呢?所谓出错就是我们调用的方法没有正常完成它的功能,比如,我要根据一个字符串创建一个文件输入流,那我就调用new FileInputStream(String str)方法,但是这个方法根据提供的字符串没有创建出我要的流,这就是出错了。要处理程序中可能发生的错误,我们首先来分析一下常见的错误有哪些。

          第一就是代码错误。你非要在程序中让1除以0,这就是你的不对的,这是代码错误,我们也叫它自己的错误,因为是你这个程序员犯的错嘛。

          第二就是用户错误。比如,我写了一个方法是根据用户提交的URL地址打开一个网页,可是用户不老实,给我这个方法提交了这样一个字符串”逗你玩”,你说气人不气人!!不管怎么说,现在我的方法肯定是无法正常完成它的功能了,这就是用户错误。

          第三是硬件错误。我有个方法是打印一个word文档,可是打印机被小偷偷走了,我还没发现。我还有个方法是在D盘创建一个10M的文件,可是D盘已经满了。这些就是硬件错误。

2、怎么处理错误

          好了,分析了常见的几种错误,我们来逐个看看怎么处理这些错误。首先是代码错误。正如前面所说,代码错误实际上就是我们程序员自己的错误,比如,你为啥在让1除以0之前不检查一下除数是0呢,如果你检查了,你就可以阻止这种错误发生。再比如,我有个方法是修改一个对象的状态,可是在修改时发现这个对象是个空对象,这就是java中常见的NullPointException,对于这样的错误,你为什么不在修改对象状态前先检查一下对象是否为空,如果你检查了,就不要修改空对象的状态嘛。总之,理论上讲,所有的代码错误,都可以通过完善代码来避免。但是人非圣贤,孰能无过,我就是忘了检查,你说怎么办吧?哼!我们暂且不表,待会再说。

        对于用户错误,理论上,我们也可以通过检查用户输入的参数来阻止错误参数,但是这个问题不是那么简单的,比如,上面的根据URL打开网页的方法,实际上,不同的浏览器支持的URL格式并不完全一致,你怎么就知道是用户输错了,而不是你孤陋寡闻了呢?

         对于硬件错误。我们当然也可以先检查一下,但是这并不能解决问题,比如我的代码检查了打印机是否存在,可是如果打印中途它坏了呢。我的代码也检查了D盘空间足够,可是如果在我往里放文件的过程中,别的程序也在里面放了文件,导致空间又不够了呢?

3、呼唤异常。

            可见对于上面三种错误,我们程序员在处理起来都是有心无力。不用怕,java为我们提供了一揽子解决方案,那就是异常!!我们把上面的三类错误全当做一个类,即Throwable。一旦采用了面向对象的思路,所有对错误的处理就变成了对这个Throwable的处理了。

            java中 已经设计好了完善的异常体系来代表各种各样的错误。根据错误的严重程度,(注意这里是根据严重程度,而不是我们前面分析的错误类型哦)。Throwable下面有两个子类一个是Error,一个是Exception,前者代表严重的错误,比如虚拟机内部发生错误或者资源耗尽了,这是靠我们程序员完善代码已经没有任何作用的错误。Exception就代表除Error之外的其他错误了。

            在Exception下面,又分出了两个分支,一个是RuntimeException,一个是非RuntimeException。这两个分支是什么意思呢?根据前面错误类型分析,我们其实也可以将错误分为两种,一种就是你自己犯了错,就是你的代码有问题,一种不是你犯了错。对于你自己犯的错,我们就称为RuntimeException,我们也叫做unchecked Exception。对于不是你犯的错,我们统称为非RuntimeException,也叫checked Exception。很显然,虚拟机在执行你的程序时,如果遇到了RuntimeException,虚拟机就知道是你犯了错误,它就会告诉你,哥们你在哪个方法的哪一行犯了错,然后希望你检查代码,消除bug。如果虚拟机在运行你的程序时遇到了checked Exception,那么虚拟机该怎么办呢?这时候虚拟机就希望你能够对这种不正常的情况进行处理了,它就会寻找不同错误的处理器。这就像在swing中,为每一个事件注册一个事件处理器一样,虚拟机希望你为每一个非RuntimeException提供一个处理器了。其实,在java中实现这种思想时很严格的,如果编译器发现你的方法要可能抛出一个checkedException,当然这个异常可能是你主动抛出来的,也可能是你的方法中调用了别的方法,别的方法抛出来的,那么编译器就会强制你不能无视这种异常,必须做出反应。

         好了,上面简单分析了一下java中的异常体系。不知道有没有讲清楚,欢迎大家批评。至于如何在程序中使用这个完善的异常体系,还是有一些奇技淫巧,也有很多争论,这里暂且不表了

1 0
原创粉丝点击