杭州网站建设洛洛科技,公司网络营销推广方案,中职省级示范校建设网站,百度刷seo关键词排名1 缘起
某天上网冲浪时#xff0c;偶然看到一个问题#xff0c;说Java的Error和Exception有什么区别#xff1f; 一句话#xff1a;不知道。并不能很清晰地描述出个中区别。 当然#xff0c;曾经也看过Throwable相关的知识#xff0c;但是#xff0c;并没有通过源码及注…1 缘起
某天上网冲浪时偶然看到一个问题说Java的Error和Exception有什么区别 一句话不知道。并不能很清晰地描述出个中区别。 当然曾经也看过Throwable相关的知识但是并没有通过源码及注释描述深入了解 之前都是看别人总结的知识这次自己通过源码梳理 还是有一些收获的 分享如下帮助读者轻松应对知识交流与考核。
2 Throwable
位置java.lang.Throwable Throwable类是Java语言中所有错误和异常的父类。 只有该类或该类子类的对象才能被JVM抛出或Java程序抛出。 同样只有该类或该类的子类才能作为catch语句的参数类型。 Throwable类关系如下图所示。
为了编译时异常检查Throwable和Throwable的任何子类不是RuntimeException或Error的子类都被视为已检查的异常。 源码如下图所示。 Error和Exception子类的实例常用于表示发生的异常。 一般这些异常是在上下文中实时创建的包含相关的信息如堆栈跟踪数据。
异常产生时throwable对象包含 1线程执行堆栈的快照 2消息字符串会提供更多的错误信息。throwable可以抑制其他throwable的传播 3产生异常的原因产生throwable的throwable即链式传播路径通过异常传播链排查产生异常的原因
产生throwable的原因 1抛出throwable的类构建在较低层的抽象上上层操作的失败是因为较低层失败。让下层抛出throwable并向外传播是糟糕的设计因为她通常与上层提供的抽象无关。并且如果下层的异常已经检查这样会将上层的API与实现的细节绑定到一起。抛出包装异常如包含异常原因允许上层将失败的详细信息传递给调用方则不会有上面的缺点。上层在不改变API基础上保留灵活修改实现尤其是方法引起的异常。 2抛出异常的方法符合通用接口不允许方法直接抛出异常原因。假设一个持久化集合符合Collection接口持久化是在java.io上实现的。假设add方法内部可以抛出IOException当Collection接口在未检查异常中包装了IOException实现可以将IOException的详情传递给调用者持久话集合的规范应表明它能够引发此类异常。
异常原因可以通过两种方式与throwable关联将原因作为参数的构造函数通过initCause(Throwable)方法。 新的throwable类希望异常原因与类相关联应该提供具有异常原因的构造函数并且代理可能是间接代理Throwable带有异常原因参数的某个构造函数。initCause方法是public因此可将异常原因与任何throwable相关联如legacy throwable他的实现先于异常链机制添加到Throwable。
按照惯例Throwable类及其子类有两个构造函数一个是无参构造函数一个接收String类型的参数用于生成详情。 此外这些子类可能与异常原因相关联应该有两个及以上构造函数一个接收Throwable一个接收String和Throwable。
2.1 Error
位置java.lang.Error Error是Throwable的子类说明问题严重不应由应用程序捕获。 此时只管抛出异常无需在程序中捕获即不使用catch捕获Error。 大多数这样的错误都是异常情况ThreadDeath虽然是“正常”情况但是仍旧不应捕获ThreadDeath是Error的子类。 Error的任何子类都不需要声明throws语句来抛出方法运行时产生的异常 因为这些错误是不应该发生的异常情况。也就是说为了在编译时检查异常Error和Error的子类均为视为未检查异常。 源码如下图所示。
2.1.1 IOError
位置java.io.IOError 发生严重I/O错误时抛出。 源码如下图所示。
2.1.2 ThreadDeath
位置java.lang.ThreadDeath 损坏的线程调用已过时Thread.stop方法时抛出ThreadDeath实例。 只有在异步终止后必须清理时应用程序才需要捕获此类的实例。 如果ThreadDeath由方法捕获需要重新抛出确保线程真正“死亡”。 如果未捕获到ThreadDeath顶级Error处理器不会打印消息。 ThreadDeath是Error的子类而不是Exception的子类 因为许多应用程序都会捕获所有的Exception然后丢弃。 源码如下图所示。 2.1.3 VirtualMachineError
位置java.lang.VirtualMachineError 抛出该异常表示Java虚拟机已经损坏或资源不足程序无法继续运行。 源码如下图所示。
2.2 Exception
位置java.lang.Exception Exception类及其子类是Throwable的一种形式表示程序想要捕获的异常。 通过该异常信息排查问题解决问题因此需要在程序中显式声明并捕获异常。 Exception类和非RuntimeException子类都是检查异常受检异常即编译时异常检查。 如果方法或构造函数的执行会引发异常并传播到方法或构造函数外需要在方法或构造函数抛出语句中声明异常。 源码如下图所示。 2.2.1 IOException
位置 该类表示发生了某种I/O异常。此类是产生失败或中断I/O操作的通用异常类。 源码如下图所示。
2.2.1.1 EOFException
位置java.io.EOFException EOFException类表示输入过程中意外到达文件尾部或流尾部。 该异常主要用于标识数据输入流到达流尾部。 需要注意的是许多其他输入操作在流结束时返回特殊值而不是抛出异常。 源码如下图所示。
2.2.1.2 FileNotFoundException
位置java.io.FileNotFoundException 当指定路径名的文件不存在时FileInputStream、FileOutputStream和RandomAccessFile构造函数会抛出该异常。 如果文件存在但是由于某些原因无法访问仍会抛出该异常如编辑只读文件。 源码如下图所示。
2.2.1.3 InterruptedIOException
位置java.io.InterruptedIOException InterruptedIOException表示I/O操作中断。抛出InterruptedIOException表明输入或输出传输已终止因为执行该传输的线程已经中断。 bytesTransferred字段表示中断前成功传输的字节数。 源码如下图所示。
2.2.1.4 ObjectStreamException
位置java.io.ObjectStreamException 抽象类对象流类异常类的父类。 源码如下图所示。 集成ObjectStreamException的子类有InvalidClassException、InvalidObjectException等 全部的子类如下图所示。
2.2.2 RuntimeException
位置java.lang.RuntimeException RuntimeException是Java虚拟机正常运行期间可以抛出的异常类的父类。 RuntimeException及其子类是未检查异常如果未检查异常可以由方法或构造函数抛出并向外传播 则无需在方法或构造函数的抛出语句中声明。 源码如下图所示。 java.lang包中继承RuntimeException的类有17个如下图所示 下面挑几个进行分享。
2.2.2.1 ArithmeticException
位置java.lang.ArithmeticException 发生算术异常时抛出。如除数为01/0。 ArithmeticException对象可以由虚拟机构造如虚拟机禁用压缩或堆栈不可写。 源码如下图所示。
2.2.2.2 IndexOutOfBoundsException
位置java.lang.IndexOutOfBoundsException 抛出IndexOutOfBoundsException说明某种索引超出了范围如数组、字符串或向量。 应用程序可继承该类表示类似的异常如ArrayIndexOutOfBoundsException类。 源码如下图所示。
2.2.2.3 NullPointerException
位置java.lang.NullPointerException
在需要使用对象的地方使用了null包括 1调用null对象的方法 2访问或变更null对象 3获取null数组的长度 4访问或变更null数据组内容 5Throwable值抛出null 应用程序可以抛出该类的实例表示非法使用null。 虚拟机可以构造NullPointerException对象如虚拟机禁用压缩和堆栈追踪不可写。 源码如下图所示。
2.2.3 ReflectiveOperationException
位置java.lang.ReflectiveOperationException 在核心反射中因反射操作抛出异常类的公共父类。 源码如下图所示。 继承ReflectiveOperationException的子类有6个如下图所示。 下面挑几个分享一下。
2.2.3.1 ClassNotFoundException
位置java.lang.ClassNotFoundException 从JDK1.4开始ReflectiveOperationException被修改为符合通用异常链机制。 “加载类时引发的异常”可能是构建时引发的通过getException()方法可以获取产生异常的原因 当然也可以通过“遗留方法”Throwable.getCause()方法获取异常原因。 源码如下图所示。
2.2.3.2 NoSuchMethodException
位置java.lang.NoSuchMethodException 无法获取某个方法时抛出的异常。 源码如下图所示。
3 小结
1Throwable是所有异常和错误的父类即Exception和ErrorThrowable包含线程执行的堆栈快照错误消息以及产生异常的链式传播路径 2Error是严重的错误如JVM错误不需要应用程序主动捕获抛出即可 3Exception是应用程序级别的异常是编写的应用程序出现的异常需要应用程序主动捕获异常信息帮助开发者排查和解决问题 4Exception常用的可分为三类IOException、RuntimeException和ReflectiveOperationException。 Throwable完整相关类的关系如下图所示。