java exception辨析和使用

前言

    学java一段时间的时候,感觉exception这个概念看起来很简单,在实际中使用的时候却常不知道该如何取舍。尤其是关于exception的各种分类,以及checked exception, unchecked exception等,哪些是应该处理,该如何处理,哪些则不必要处理呢?各种exception,傻傻分不清。这里结合自己的一些理解,一并做一个讨论。

Exception的结构体系以及定义

    我们在设计和执行程序的时候,往往会有太多其他的因素来影响到程序的正常的执行。比如说我们连接网络的程序出现网络连接断开,读取文件的时候发现文件不存在或者文件解析错误,访问某些资源的时候发现运行的程序没有足够的权限,等等。这些东西可能存在,在发生的时候像一个意外的发生,导致程序没法正常运行下去。在java里,这些都被定义为异常(exception)。

    由于异常的导致原因、处理方式等在具体的情况下不同,所以它有一个整个体系化的定义。这里是一个关于exception系列相关类的结构图:

    为了后面举例和讨论方便,在图中也列举了一些特定的exception。从图中我们可以看到,所有exception相关的类都继承自类Throwable,在它的下面又划分为两个部分,Exception和Error。在Error这一块,一些经常听到过的Error如OutOfMemoryError、StackOverflowError就来自VirtualMachineError。在Exception这一边,有IOException、SQLException等异常,另外一个比较典型的就是RuntimeException,我们见过的有的异常如NullPointerException和IllegalArgumentException就继承自它。

    从结构图来看,这里的分类比较有意思。我们也可以笼统的看出点名堂来了。在Error和Exception这两个大类里,一些比较严重的问题,比如java虚拟机宕机了,内存被耗光了之类的问题,都定义在Error这个类下面。这些问题,我们可以看成是很严重的问题,一般是没法恢复的,在上面运行的程序也没法自己去处理。这就好比我们在一台机器上要运行一个程序,想通过这个程序来保证当机器宕机的时候来保存一些数据或者做一些恢复处理的工作,这几乎是不可能的。因为机器一宕机,里面的程序也就挂了,皮之不存,毛将焉附?

    另外一类的Exception则不一样,这里发生的问题一般不是严重到了宕机之类使得程序都没法运行的程度。比如我们这里的IOException,可能是我在读取某个文件的时候出错了,但是整个运行程序的虚拟机还是好好的。而且我这个读取文件的程序也可以继续运行,取决于程序设计者的期望。实际上,我们大部分自定义的exception都是通过继承自类Exception。

    关于Exception这个大类里的不同实际上他们的应用情景也有一定的差别。一个典型的就是RuntimeException,从字面上我们就可以看到,它主要是关于运行时的,在运行的时候出现的异常。对于这一类的异常,他们有的可以作为一种程序设计错误的提示。我们针对这种情况需要分析程序的设计及实现去修正这些错误。而有的是程序运行时碰到的问题,这种问题有的是运行的时候依赖于外部特定的环境或者设置,我们不能在程序里做其他有效的措施来恢复,就没必要去捕捉和处理它。

checked exception, unchecked exception

    在很多场景下,常见的一个讨论就是checked exception和unchecked exception。对于checked exception来说,参照前面的类结构图,它官方的定义是继承自Exception这个类族里,除了RuntimeException的所有类。很多我们可以自定义的异常也归结到这一类里。常见的导致这种异常的原因有如下:非法的输入、网络连接或数据库连接错误等等。

    对于unchecked exception来说,它主要指发生在运行时出现的错误,常见的一些原因比如有数组访问越界、传入null空指针错误等。

常见的一些处理手法

    前面既然我们列举和讨论了这两类异常,那么当碰到这些异常的时候,我们该怎么去处理呢?从很多的书上我们看到的一个笼统的说法就是要保证一下几点:1. 提醒用户错误发生。 2. 保存所有必要的当前工作。 3. 允许用户优雅的退出程序。其实以上说的这几点都只是一个很含糊的描述,在具体问题的时候,我们到底该怎么办呢?这里,针对个人的一些体会,总结了这么几点。

总的来说,根据问题和具体应用场景的需要来做处理。对于checked exception来说,常见几种办法是:

1. 写log,用常用的log framework将错误信息记录下来。在记录了log信息之后再将异常信息向上传递。也有可能在这里直接退出。

2. 对于数据库之类的错误来说,可能需要关闭连接等信息。

3. 对于有的爬虫类应用来说,碰到这样的问题其实是很常见的,如果我们让它碰到异常就退出了并不是一个合理的选择,有时候可能是服务器繁忙,有的时候可能是那边网络暂时的阻塞。我们可能需要做一个重试的操作,比如说让当前的线程sleep多少秒,然后重试若干次,如果还是失败了再记录错误信息,退出。

4. 在一些用户交互的程序里,可能需要在界面做一些提示,比如显示某些特定的提示文字或者弹出提示错误信息的对话框,然后重置原来的进程让用户可以后面重试。

    另外,对于一些unchecked exception来说,我们某些情况下也是可以捕捉和处理的。我以前曾经做过的某个项目有这么一个要求。在一些特定的配置文件项里设置了一些参数用来设定程序的属性。有的值表示合法的,可以enable它,有的则表示disable。但是如果用户在配置文件项里如果故意输入错误的信息该怎么办呢?这里为了项目的健壮性就统一将这些错误的配置信息解释成这些属性是disable的。当然,这里是需要结合具体应用的场景来看是否有意义。有的则确实是需要去作为一种unchecked exception让它出错或者终止,有的则可以继续运行。

总结

    以前写程序的时候偶尔会想,要是写的程序都是在一个很理想的状态就好了。那个时候所有的输入和输出都是正确的,没有运行时候的各种意外发生。这样就不会有这么个讨厌的exception处理了。exception产生的很大一部分场景是在于我们自己设计的模块在和其他部分衔接的时候,我们不能保证其他部分传递进来的东西就是我们所希望的,所以为了保证程序的健壮性就需要考虑这么些场景。exception像一个声音提醒我们,人世间不如意,十有八九。关于checked exception和unchecked exception,笼统的来说是checked exception是有必要通过程序来处理的,在一些情况下可以在程序里重试或者恢复程序的执行。而对于unchecked exception,通常意味着他们要么是很严重的运行错误, 你没法恢复也没法处理,所以就让它这样吧,还有一些情况可能是本身程序的问题,需要设计者考虑程序设计和实现里的错误。在我个人看来,在某些场景下,捕捉unchecked exception并做一些处理也是有意义的。他们两者虽然有这么一个可以处理以及不可以处理的界限,但是不是绝对的,还是要具体问题具体分析。

参考材料

http://stackoverflow.com/questions/6115896/java-checked-vs-unchecked-exception-explanation

http://www.roseindia.net/java/java-exception/listofjavaexception.shtml

effective java

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值