怎么开亚马逊跨境电商店铺网站页面结构怎么做有利于优化
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
 发生算术异常时抛出。如除数为0,(1/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数据组内容;
 (5)Throwable值抛出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 小结
(1)Throwable是所有异常和错误的父类,即Exception和Error;Throwable包含线程执行的堆栈快照,错误消息以及产生异常的链式传播路径;
 (2)Error是严重的错误(如JVM错误),不需要应用程序主动捕获,抛出即可;
 (3)Exception是应用程序级别的异常(是编写的应用程序出现的异常),需要应用程序主动捕获,异常信息帮助开发者排查和解决问题;
 (4)Exception常用的可分为三类:IOException、RuntimeException和ReflectiveOperationException。
 Throwable完整相关类的关系如下图所示。

