填坑,整理下Java的常用异常。正确使用异常在实际编码中非常重要,但面试中的意义相对较小,因为对异常的理解和应用很难通过几句话或几行代码考查出来,不过我们至少应答出三点:异常类的继承关系、常用异常类、常用异常类的使用场景,下文将围绕这三点介绍。

异常类的继承关系

Java中,所有异常都继承自Throwable类(一个完整可用的类)。整体上分为Error、Exception两个大类,Exception大类又分为UncheckedException(继承于RuntimeException)和CheckedException(继承于Exception,但不继承于RuntimeException)。

为了帮助理解,我在每个类别下都给出了两个常用子类,如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。

上述异常类都是很常见的,但其中几个异常类设计的不好,需要注意:

  • ConcurrentModificationException:实现“快速失败”的机制,但实际上,“快速失败”机制本身仍然无法保证并发环境下安全性,参考源码|从源码分析非线程安全集合类的不安全迭代器。因此,虽然该异常很常见,不要去依赖它。
  • JSONException:常见于json字符串解析失败的情况,但遮蔽了大量的失败细节,往往很难根据该异常作出处理。如果项目中大量使用json,建议使用第三方的json解析库,如gson等。
  • UnsupportedOperationException:这是一种编码上的恶性妥协,经常在抽象类的成员方法中被用户主动抛出,表示该方法还未实现等,但由于是UncheckedException,运行期才能够发现,完全无益于编码期间的安全性。自己编码时尽量不要使用。
  • SQLException:与JSONException原因相似,但其遮蔽的失败细节范围更广。同时,SQLException还是一个CheckedException,在不能解决问题的情况下,又使代码变的臃肿不堪。建议同。如果做Java Web开发,热门的ORM库都能解决上述问题。

常用异常类的使用场景

常用异常还是有点多,下面分别讲解上述三个类别的使用场景,并在每个类别中选一个例子进行讲解。

Error

Error通常描述了系统级的错误,并且程序猿无法主动处理——当然,系统级错误也有可能由代码间接导致,这不在我们的讨论范围内。发生系统级错误的时候,系统环境已经不健康了,因此,Error不强制捕获或声明,也就是不强制处理,一般情况下只需要把异常信息记录下来(如果能记下当时的系统快照更好)。

OutOfMemoryError

当可用内存不足时,会由JVM抛出OutOfMemoryError。一般由三种原因导致:

  • 堆设置过小,不满足正常的内存需求
  • 代码中存在内存泄露,占用了大量内存而不能被回收
  • 选择的GC算法与某些极端的应用场景不匹配,内存碎片过多,没有足够大的连续空间分配给对象

JVM抛出OutOfMemoryError前,会尝试进行一次Full GC,如果GC后可用内存还是不足,才会抛出OutOfMemoryError。因此,这时程序猿必然无法主动处理这一问题,只能等程序崩溃后再去查证原因。

查证OutOfMemoryError的技巧足以单开一篇文章了,本文不作深入。

UncheckedException

严格来说,Error也可以被划归UncheckedException,但我们更习惯用UncheckedException描述运行期发生,通常由于代码问题直接引起的程序相关的错误,并且程序猿无法主动处理。注意区分,系统级错误都应该用Error描述。UncheckedException发生的大部分情况是代码写挫了,因此,UncheckedException也不强制捕获或声明,也就是不强制处理,一般情况下记下日志即可。

不同的是,如果可能,要保证UncheckedException是可控的(在异常被动抛出前检查并主动抛出)。

JSONException就是不可控的。

NullPointerException

NullPointerException是最常见的UncheckedException。如果在一个空指针上引用方法或变量等,则运行期会抛出NullPointerException。空指针让程序变的不可控:如果任由空指针在程序运行期随意传递、使用,我们将无法确定程序的行为,也无法确定捕获NullPointerException时程序所处的状态。

解决这一问题的方法很简单:

  • 尽早检查并主动抛出异常
  • 单独、提前处理边界条件
  • 尽量不使用null表示状态,特别是在集合中

前两条原则通用于大部分UncheckedException,可参考String#toLowerCase()的例子。第三条原则需要在代码的健壮与简洁之间做出权衡,有限保证简洁清晰,需要健壮再去健壮。

CheckedException

猴子对CheckedException的理解不到位,如果各位有更好的理解希望能交流一下。以下讲猴子“不到位”的理解。

CheckedException描述了外部环境导致的不太严重的错误,程序猿应该主动处理。注意与系统级错误区分,系统级错误通常是不可恢复的。因此,CheckedException强制捕获或声明,程序猿必须处理。记录日志,包装后再次抛出,在方法签名中声明,是三种最常见的做法。

同UncheckedException一样,CheckedException也要保证是可控的。对CheckedException的可控性要求更高,不仅要主动检查,还要在捕获到异常时,作出合适的处理。

不过,猴子认为大量CheckedException的存在就是个错误。比如FileAlreadyExistsException,更应该由用户主动检查发现,而不应该依赖于异常。对于可以处理的异常,本质上相当于控制流问题,用异常去表达反而让控制流变模糊。不过有时候猴子写小项目,也会为了简化代码,直接将相关异常声明在方法签名中,并一路声明干到main方法。恩,everything is a trade-off。

IOException

产生IOException的原因非常多,但很多时候我们并不关心细节原因,因为文件系统是一个不太可控的因素,这时我们可以以IOException为粒度处理;某些需要关心细节的异常情况,则应使用IOException的子类,以分情况处理。

前面总结的FileAlreadyExistsException、FileNotFoundException、UnknownHostException等,都是IOException的子类。这三种异常恰好都是可以处理的。

挖坑,InterruptedException也相当重要,后面要专门写一篇来整理。

总结

实际的编码工作中,我们应正确的使用异常表达代码设计,并尽可能使用JDK提供的异常类。JDK内置了非常多的异常类,我们只需要掌握一些常用的异常类,然后举一反三。

Java学习交流QQ群:589809992  禁止闲聊,非喜勿进!

Java常用异常整理的更多相关文章

  1. JAVA常用设计模式整理

    设计模式:一个程序员对设计模式的理解:“不懂”为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开一把 ...

  2. java 常用异常及作用

    先看看图, Exception就明白了 关于异常 大体分为 不可查异常 可查异常 runtimeException三类~异常都继承throwable这个类~ 下面有error和Exception两大类 ...

  3. JAVA常用异常类

    算数异常类:   ArithmeticExecption 空指针异常类:    NullPointerException 指定类不存在:    ClassNotFoundException 字符串转换 ...

  4. java 常用工具整理

    mapUtil map操作工具类 <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 ...

  5. Java-最常用的Java日志框架整理

    Java-最常用的Java日志框架整理 前言 Java程序员,我们开发了很多Java应用程序,包括桌面应用.WEB应用以及移动应用.然而日志系统是一个成熟Java应用所必不可少的,在开发和调试阶段,日 ...

  6. MySQL常用指令,java,php程序员,数据库工程师必备。程序员小冰常用资料整理

    MySQL常用指令,java,php程序员,数据库工程师必备.程序员小冰常用资料整理 MySQL常用指令(备查) 最常用的显示命令: 1.显示数据库列表. show databases; 2.显示库中 ...

  7. 你真的会阅读Java的异常信息吗?

    给出如下异常信息: java.lang.RuntimeException: level 2 exception at com.msh.demo.exceptionStack.Test.fun2(Tes ...

  8. 【linux】---常用命令整理

    linux常用命令整理 一.ls命令 就是list的缩写,通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录.文件夹.文件权限)查看目录信息等等 常用参数搭配: l ...

  9. 北京Java笔试题整理

    北京Java笔试题整理 1.什么是java虚拟机?为什么ava被称作是"平台无关的编程语言? 答:Java虚拟机可以理解为一个特殊的"操作系统",只是它连接的不是硬件,而 ...

随机推荐

  1. vue-router的两种模式的区别

    众所周知,vue-router有两种模式,hash模式和history模式,这里来谈谈两者的区别. ### hash模式 hash模式背后的原理是`onhashchange`事件,可以在`window ...

  2. Centos 6系统修复grub

    author:JevonWei 版权声明:原创作品 错误界面如下时,应该是grub的stage数据有缺失,应该从新安装grub GRUB引导的stage1阶段损坏,系统启动会直接进入光盘引导界面,st ...

  3. JavaScript实现隔行换颜色

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  4. 【Beta】阶段 第一次Daily Scrum Meeting

    每日任务 1.本次会议为第一次 Meeting会议: 2.本次会议在周一下午16:40,课间休息时间在禹州楼召开,召开本次会议为10分钟. 一.今日站立式会议照片 二.每个人的工作 (有work it ...

  5. 团队作业8——第二次项目冲刺(Beta阶段)5.25

    1.当天站立式会议照片 会议内容: 本次会议为第六次会议 本次会议在陆大楼3楼召开,本次会议内容: ①:检查总结上次任务完成情况 ②:安排今天的分工 ③:对昨天的问题进行讨论 ④:遇到困难,及时群里反 ...

  6. 201521123081《Java程序设计》 第8周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 参考资料:XMIND 1.2 选做:收集你认为有用的代码片段 2. 书面作业 本次作业题集 集合 Q1. Li ...

  7. 201521145042《Java程序设计》第14周学习总结

    MySql操作视频与数据库相关jar文件请参考QQ群文件. 本次作业参考文件 数据库PPT 0. 本周课程设计发布 Java课程设计 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总 ...

  8. 201521123095 《Java程序设计》第9周学习总结

    1. 本周学习总结 2. 书面作业 本次PTA作业题集异常 Q1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己以前编写的代码中经常出现什么异常.需要捕获吗(为什么)?应如何 ...

  9. 201521123057 《Java程序设计》第12周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 1.字符流与文本文件:使用 PrintWriter(写),BufferedReader(读) ...

  10. 201521123028 《Java程序设计》第11周学习总结

    1. 本周学习总结 关于互斥同步访问 synchronized关键字 -wait.notify和notifyAll Lock和Condition方法 -condition.await() //类似ob ...