Java常用异常整理
填坑,整理下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常用异常整理的更多相关文章
- JAVA常用设计模式整理
设计模式:一个程序员对设计模式的理解:“不懂”为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开一把 ...
- java 常用异常及作用
先看看图, Exception就明白了 关于异常 大体分为 不可查异常 可查异常 runtimeException三类~异常都继承throwable这个类~ 下面有error和Exception两大类 ...
- JAVA常用异常类
算数异常类: ArithmeticExecption 空指针异常类: NullPointerException 指定类不存在: ClassNotFoundException 字符串转换 ...
- java 常用工具整理
mapUtil map操作工具类 <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 ...
- Java-最常用的Java日志框架整理
Java-最常用的Java日志框架整理 前言 Java程序员,我们开发了很多Java应用程序,包括桌面应用.WEB应用以及移动应用.然而日志系统是一个成熟Java应用所必不可少的,在开发和调试阶段,日 ...
- MySQL常用指令,java,php程序员,数据库工程师必备。程序员小冰常用资料整理
MySQL常用指令,java,php程序员,数据库工程师必备.程序员小冰常用资料整理 MySQL常用指令(备查) 最常用的显示命令: 1.显示数据库列表. show databases; 2.显示库中 ...
- 你真的会阅读Java的异常信息吗?
给出如下异常信息: java.lang.RuntimeException: level 2 exception at com.msh.demo.exceptionStack.Test.fun2(Tes ...
- 【linux】---常用命令整理
linux常用命令整理 一.ls命令 就是list的缩写,通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录.文件夹.文件权限)查看目录信息等等 常用参数搭配: l ...
- 北京Java笔试题整理
北京Java笔试题整理 1.什么是java虚拟机?为什么ava被称作是"平台无关的编程语言? 答:Java虚拟机可以理解为一个特殊的"操作系统",只是它连接的不是硬件,而 ...
随机推荐
- [js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表
所谓组合模式,就是把一堆结构分解出来,组成在一起,现实中很多这样的例子,如: 1.肯德基套餐就是一种组合模式, 比如鸡腿堡套餐,一般是是由一个鸡腿堡,一包薯条,一杯可乐等组成的 2.组装的台式机同理, ...
- 我的前端故事----我为什么用GraphQL
背景 今年我在做一个有关商户的app,这是一个包含商户从入网到审核.从驳回提交到入网维护的完整的生命周期线下推广人员使用的客户端软件,但故事并没有这么简单... 疑问 随着app的逐渐完善,遇到的问题 ...
- 七字真言解读TCP三次握手
三次握手所谓的"三次握手"即对每次发送的数据量是怎样跟踪进行协商使的发送和接收同步,根据所接收到的数据量而确定的数据确认数及数据发送.接收完毕后何时撤消联系,并建立虚连接. 一.七 ...
- js文件引用方式及其同步执行与异步执行
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp74 任何以appendChild(scriptNode) 的方式引入 ...
- 【小白成长撸】--顺序栈(C语言版)
// 顺序栈.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h"//test1.0--栈表仅限Int类型 #include <stdio. ...
- 蓝桥杯试题利用数学知识经典解法,1.三个空瓶子换一瓶水;2.猜最后一个字母——猎八哥FLY
本博客为本人原创,转载请在醒目位置表明出处. 1.乐羊羊饮料厂正在举办一次促销优惠活动.乐羊羊C型饮料,凭3个瓶盖可以再换一瓶C型饮料,并且可以一直循环下 去,但不允许赊账.请你计算一下,如果小明不浪 ...
- grep&正则表达式
p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; f ...
- [转载]在instagram上面如何利用电脑来上传图片
原文地址:在instagram上面如何利用电脑来上传图片作者:小北的梦呓 我们都知道instagram是一个手机版的app,instagram官方不支持通过电脑来上传图片,而利用手机又很麻烦,那么如果 ...
- MySQL (五)--连接查询简介、 交叉连接、 内连接、外连接、自然连接、温馨小提示
1 连接查询简介 将多张表(可以大于2)进行记录的连接(按照某个指定的条件进行数据拼接). 最终结果:记录数可能会有变化,字段书一定会增加(至少两张表的合并). 连接查询:join,使用方式:左表 j ...
- HTML的基本标签及语法
一.HTML基本标签head部分 HTML文档的基本结构 <!DOCTYPE html> <html> <head> <meta charset=" ...