谈谈java中的异常处理规范

java中的异常分为三大块,分别是error,checkedException,uncheckedException

三者设计理念不一样,体现了java设计者对不同异常情况的分类

error表示发生了意料之外的错误,大部分情况下,会使得程序处于不可恢复的状态,不需要也不应该被捕获,比如OutOfMemoryError StackOverFlowError NoClassDefFoundError;这种异常发生后,只能乖乖的查问题,该改配置改配置,该改代码改代码了

checkedException,uncheckedException都属于exception,是指发生了可以预料的意外情况可以人为干预进行修复处理,也可以选择忽略让它抛到jvm中,jvm会帮我们中止异常线程,打印异常堆栈

checkedException需要显式的catch,否则编译不会通过,在用到一些抛出checkedException的方法时,往往会觉得好讨厌,但这种异常的设计本意就是为了让你catch住然后进行修复处理

比如Class.forName(className),会抛出ClassNotFoundException

FileInputStream in=new FileInputStream(file),会抛出FileNotFoundException

Thread.sleep(time),会抛出InterruptedException

意思其实很明确,就是强制调用者考虑异常情况如何处理,比如catch到FileNotFoundException后,是不是可以创建一个File,重试一次;catch到InterruptedException后需不需要检查下资源是否已就位,就位了就继续往下走流程

但是!业界有一种争论(甚至可以算是某种程度上的共识),java的checkedException也许是个设计错误,我们说了,它的设计理念是让你捕获异常,然后修复程序,我们上面也举了两个修复的例子,但是大部分情况下,这种异常发生后,要嘛是代码写的有问题、参数传错了这种编码错误导致的异常,要嘛根本就不可能恢复,比如ClassNotFoundException,似乎没有好的处理方法,更别提恢复了。目前很多开源项⽬,已经明确地摆脱了检查异常,⽐如SpringHibernate等,仅使用运行时异常,而这种便利性是它们流行的主要因素之一

所以说,checkedException的设计本意没啥问题,但是对于它的使⽤,已经⼤⼤偏离了最初的设计⽬的,大部分的checkedException是无法恢复的,却强制使用者进行try cahch硬编码,带来了很大的不便。

如果我们用到了这种抛出checkException的方法,只能乖乖catch住,然后能修复的还是尽量修复,不能修复的不要啥也不干,堆栈好歹要打印下;在我们自定义异常时,要认真的考虑下,这个异常抛出后,是否存在修复的可能性,如果无法修复,请不要使用checkedException!

uncheckException不需要显式的catch,大部分情况下是触犯了一些明确的规则,比如NullPointException,ClassCastException,IllegalArgumentException,ArrayIndexOutOfBoundsException

这些异常其实大多可以通过事先检查而避免,比如

if(obj!=null){obj.do();}

if(index>=arr.length){return;}

检查动作应该尽量做好!减少对这类异常的捕获,防止过多的catch影响代码美观性,以及代码执行效率,有些同学喜欢在一大段代码上来个try catch(Exception e),这是非常不负责任的做法;

尽量去检查代码,不代表盲目的检查,有些同学不管啥方法,上来就是对参数一顿检查,这样也很不好,如果已经确定了这个obj不会为null,那就不要多写个if判断;

另外,很多情况下,遇到这类异常后,因为是明确的触犯了一些规则,所以流程正常中断是没问题的,也就是不需要catch,交给jvm去处理就好了;这种时候,不怕你不catch,就怕你catch了啥也不干,那遇到问题基本只能靠猜了!

上面说了,我们会自定义一些异常,很多时候,都是些参数错误相关的异常,uncheckedException就够了,再次强调下,如果要抛出的异常情况无法修复,不要使用checkedException!

程序员最基本的素质应该是对自己的代码负责,我们想的应该是怎么把代码写的更好,而不是怎么才省事;

猜你喜欢

转载自blog.csdn.net/wb_snail/article/details/106559559