填坑,整理下Java的经常使用异常。正确使用异常在实际编码中很是重要,但面试中的意义相对较小,由于对异常的理解和应用很难经过几句话或几行代码考查出来,不过咱们至少应答出三点:异常类的继承关系、经常使用异常类、经常使用异常类的使用场景,下文将围绕这三点介绍。git
Java中,全部异常都继承自Throwable类(一个完整可用的类)。总体上分为Error、Exception两个大类,Exception大类又分为UncheckedException(继承于RuntimeException)和CheckedException(继承于Exception,但不继承于RuntimeException)。github
为了帮助理解,我在每一个类别下都给出了两个经常使用子类,如Error包括OutOfMemoryError、AssertionError等;UncheckedException包括NullPointerException、IllegalArgumentException;CheckedException包括IOException、InterruptedException。面试画异常类的继承关系时,要求能清楚的说明几个类别并分类别举几个经常使用的异常类。面试
下面分类别扩充一下经常使用的异常类,字典序排序:算法
类别 | 经常使用异常类 |
---|---|
Error | AssertionError、OutOfMemoryError、StackOverflowError |
UncheckedException | AlreadyBoundException、ClassCastException、ConcurrentModificationException、IllegalArgumentException、IllegalStateException、IndexOutOfBoundsException、JSONException、NullPointerException、SecurityException、UnsupportedOperationException |
CheckedException | ClassNotFoundException、CloneNotSupportedException、FileAlreadyExistsException、FileNotFoundException、InterruptedException、IOException、SQLException、TimeoutException、UnknownHostException |
须要着重理解的是UncheckedException。json
上述异常类都是很常见的,但其中几个异常类设计的很差,须要注意:安全
经常使用异常仍是有点多,下面分别讲解上述三个类别的使用场景,并在每一个类别中选一个例子进行讲解。并发
Error一般描述了系统级的错误,而且程序猿没法主动处理——固然,系统级错误也有可能由代码间接致使,这不在咱们的讨论范围内。发生系统级错误的时候,系统环境已经不健康了,所以,Error不强制捕获或声明,也就是不强制处理,通常状况下只须要把异常信息记录下来(若是能记下当时的系统快照更好)。源码分析
当可用内存不足时,会由JVM抛出OutOfMemoryError。通常由三种缘由致使:编码
JVM抛出OutOfMemoryError前,会尝试进行一次Full GC,若是GC后可用内存仍是不足,才会抛出OutOfMemoryError。所以,这时程序猿必然没法主动处理这一问题,只能等程序崩溃后再去查证缘由。线程
查证OutOfMemoryError的技巧足以单开一篇文章了,本文不做深刻。
严格来讲,Error也能够被划归UncheckedException,但咱们更习惯用UncheckedException描述运行期发生,一般因为代码问题直接引发的程序相关的错误,而且程序猿没法主动处理。注意区分,系统级错误都应该用Error描述。UncheckedException发生的大部分状况是代码写挫了,所以,UncheckedException也不强制捕获或声明,也就是不强制处理,通常状况下记下日志便可。
不一样的是,若是可能,要保证UncheckedException是可控的(在异常被动抛出前检查并主动抛出)。
JSONException就是不可控的。
NullPointerException是最多见的UncheckedException。若是在一个空指针上引用方法或变量等,则运行期会抛出NullPointerException。空指针让程序变的不可控:若是任由空指针在程序运行期随意传递、使用,咱们将没法肯定程序的行为,也没法肯定捕获NullPointerException时程序所处的状态。
解决这一问题的方法很简单:
前两条原则通用于大部分UncheckedException,可参考String#toLowerCase()的例子。第三条原则须要在代码的健壮与简洁之间作出权衡,优先保证简洁清晰,须要健壮再去健壮。
猴子对CheckedException的理解不到位,若是各位有更好的理解但愿能交流一下。如下讲猴子“不到位”的理解。
CheckedException描述了外部环境致使的不太严重的错误,程序猿应该主动处理。注意与系统级错误区分,系统级错误一般是不可恢复的。所以,CheckedException强制捕获或声明,程序猿必须处理。记录日志,包装后再次抛出,在方法签名中声明,是三种最多见的作法。
同UncheckedException同样,CheckedException也要保证是可控的。对CheckedException的可控性要求更高,不只要主动检查,还要在捕获到异常时,做出合适的处理。
不过,猴子认为大量CheckedException的存在就是个错误。好比FileAlreadyExistsException,更应该由用户主动检查发现,而不该该依赖于异常。对于能够处理的异常,本质上至关于控制流问题,用异常去表达反而让控制流变模糊。不过有时候猴子写小项目,也会为了简化代码,直接将相关异常声明在方法签名中,并一路声明干到main方法。恩,everything is a trade-off。
产生IOException的缘由很是多,但不少时候咱们并不关心细节缘由,由于文件系统是一个不太可控的因素,这时咱们能够以IOException为粒度处理;某些须要关心细节的异常状况,则应使用IOException的子类,以分状况处理。
前面总结的FileAlreadyExistsException、FileNotFoundException、UnknownHostException等,都是IOException的子类。这三种异常刚好都是能够处理的。
挖坑,InterruptedException也至关重要,后面要专门写一篇来整理。
实际的编码工做中,咱们应正确的使用异常表达代码设计,并尽量使用JDK提供的异常类。JDK内置了很是多的异常类,咱们只须要掌握一些经常使用的异常类,而后触类旁通。
本文连接:Java经常使用异常整理
做者:猴子007
出处:monkeysayhi.github.io
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布,欢迎转载,演绎或用于商业目的,可是必须保留本文的署名及连接。