java基础-异常机制
-
Java异常时Java提供的一种识别及响应错误的一致性机制,Java异常机制可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程序的健壮性
-
异常的层次结构
-
Throwable
- Throwable是Java语言中所有错误与异常的超类,它包含两个子类,Error和Exception,他们通常用于指示发生了异常情况。
- Throwable包含了其线程创建时执行堆栈的快照,它提供了print Stack Trace()等接口用于获取堆栈跟踪数据等信息。
-
Error
- 程序中无法处理的错误,标识运行应用程序中出现了严重的错误。(OutOfMemoryError,VirtualMachineError,StackOverFlowError)
- 这些错误时不授检异常,并非时代码性错误,因此当此类错误发生时,应用程序不应当想着去处理此类错误,并且我们不应该实现任何新的Error子类
-
Exception
-
程序本身可以捕获并且可以处理的异常。这类异常有分为两类,运行时异常、编译时异常
-
运行时异常
- 都是RunTimeException类及其子类异常,这些异常都是不检查异常,程序可以选择捕获处理也可以不处理,因为这些异常一般都是由于逻辑错误引起的,程序应该从逻辑角度尽可能避免这种异常的发生
- eg:NullPointException、IndexOutOfBoundsException。。。
-
非运行时异常(编译异常)
-
RuntimeException以外的异常,类型上属于Exception类及其子类,是必须要经过处理的异常,如果不处理程序将不能编译通过
-
eg:IOException、SQLException
-
-
-
可查异常和不可查异常
- 可查异常:编译器要求必须处置的异常 (除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。)
- 不可查异常:编译器不强制处置的异常( 包括运行时异常(RuntimeException与其子类)和错误(Error))
-
-
-
异常基础
-
关键字
- try-用于监听
- catch-用于捕获异常
- finally-finally语句快总是会被执行,主要用于回收在try块中打开的物理资源,只有当finally快中语句执行完成后,才会去执行try或者catch中的return和throw操作,如果finally中使用了return或throw则不会跳回执行,直接停止。
- throw-用于抛出异常
- throws-用在方法签名中,用于声名该方法可能抛出异常。
-
异常的捕获
- try-catch
- try-catch-finally
- try-finally
- try-with-resource:java7中引入,上面的操作中finally操作中的close方法也可能抛出IOException从而覆盖原始异常,若使用这种方法去关闭资源的话,close方法抛出的异常会被抑制,抛出的仍然是原始异常。被抑制的异常会由addSusppressed方法添加到原来的异常,可以通过;getSupperssed方法来获取。
-
-
实践
-
深入理解异常
-
JVM异常处理机制(异常表)
- 将上述代码进行反编译
- from 可能发生异常的起始点
- to 可能发生异常的结束点
- target 上述from和to之间发生异常后的处理者的位置
- type 异常处理者处理的异常的类信息
-
JVM异常表运行流程
- JVM会在当前出现异常的方法中查找异常表看是否由何时的处理者来处理。
- 如果当前异常表不为空,并且异常复合处理者的from和to节点,type也匹配,则JVM调用位于target的调用者来处理
- 如果上一条中没有找到合理的处理者,则继续向下查找异常表中的剩余条目
- 如果当前的异常表无法处理,则向上查找刚刚调用该方法的调用处,并重复上面的操作
- 如果所有的栈帧被弹出而异常还没有被处理,则抛出当前的Thread,Thread则会终止
- 如果当前线程为最后一个非守护线程,并且未处理异常,就会导致JVM终止运行
- finally中的语句快在异常表中以(type=any)形式存在,也就是说,finally中的部分已经被提取到了try和catch部分中去。
-
建立一个异常对象是建立一个普通Object对象耗时的约20倍,而爆出、接住一个异常对象,所花费实践大约是建立异常对象的的四倍。
-