JAVA异常体系详解

在构建框架统一异常管理机制之前,需要对java的异常体系深入理解

 

一、java中的 异常分类

1、 java.lang.Throwable 是java中异常的基类,通过Throwable 的集成实现关系可以看出, Error 、Exception 都是继承与Throwable,所以Throwable是java语言体系中异常的超类

JAVA异常体系详解_第1张图片

(1)检查性异常

 

  • 可查异常:Exception 中非运行时异常

  • 编译器在代码校验时要求必须处置的异常,不处理编译不通过

  • 可预见的

  • 一旦发生必须处理:try catch 捕获 或者 throws 向上抛出

  • 异常发生后,如果不做处理,线程中断

(2)非检查性异常(Error、运行时异常 RuntimeException及其之类)

  • 编译器不要求强制处置

  • 分为Error 及运行时异常及其之类

  • 运行时异常及其之类可以在程序中捕获也可以不做捕获,编译都可以通过,尽可能的注意程序逻辑避免运行时异常(NullPointerException、IndexOutOfBoundsException)

  • 如果运行过程中发生非检查性异常,处理的办法是找到发生异常的错误代码或者服务器硬件资源问题处理掉,而不是捕获,这实际上是java多异常做的扩展、容错

(3)Error


1) Error是程序无法处理的错误,所以Error异常是不需要捕获的
2)Error异常是不应该发生的异常情况,所以在程序编译时是不被检查的(非检查性异常)
3)程序一旦发生Error异常,线程停止,web项目通常会报500页面(OutOfMemoryError、ThreadDeath、NoClassDefFoundError)
4)一个设计合理的程序是不应该出现Erro错误的,一旦出现也不需要用程序补救的方式来处理Error异常

JAVA异常体系详解_第2张图片

JAVA异常体系详解_第3张图片

(4)Exception
1) 程序本身可以处理
2)分为运行时异常和非运行时异常,运行时异常为非检查性异常,非运行时异常为检查性异常
3)当程序中出现非运行时异常时(Exception中除RuntimeException及其之类之外),要不捕获、要么向上抛出throws,否则线程中断

JAVA异常体系详解_第4张图片

二、根据业务需求创建自己的异常


(1)java自带异常不能够说明系统发生异常的具体情况
(2)根据业务场景设置可读性强、易于理解、方便系统业务流转的异常(如前后端多场景交互等)
(3)一般通过异常类的名称或内部提示语进行设计,指明用意,便于理解

 

三、异常处理策略


(1)如果确定该方法中会发生那些异常并知道如何处理,处理后的业务流程走向也明确,则进行异常捕获并处理
(2)如果不确定该方法中会发生那些异常,或不知道怎么处理这些异常,则向上抛出,又最后一层异常拦截器进行管理

四、java异常捕获、抛出实现

 

1、try、catch 、 finally
  try {  
//异常监控区或叫作代码实现区
              // 程序业务实现代码  
          } catch (T1 t1){  
              // 捕获异常类型为T1的异常 
          } catch (T2 t2){  
               //捕获异常类型为T2的异常   
          }  finally{
//最后处理实现,不管异常是否捕获都会执行的代码
}

2、代码实现区如果有异常抛出,则该方法立即创建异常对象(异常的类型已经确定了),并将该异常抛出监控区域外,寻找匹配类型兼容的catch子句,若匹配成功(父类及其本身都可匹配),则执行该catch子句的实现,异常捕获处理结束,如果有finally定义则继续执行finally代码块。


3、只要有一个catch子句匹配成功,则整个捕获过程结束,所以在实现多级catch子句处理时要注意T1、T2、T3....异常类型的归属关系,例如父子关系的异常类型 : Exception是CloneNotSupportedException的父类,而CloneNotSupportedException 是 ServerCloneException 的父类, 根据只要catch匹配整个捕获就结束这个原理,可以得出如果把ServerCloneException 放到第三级catch,把CloneNotSupportedException 放在第二级catch,Exception放在第一级catch,即:

 

try {  
//异常监控区或叫作代码实现区
              // 程序业务实现代码  
          } catch (Exception t1){  
              // 捕获异常类型为T1的异常 
          } catch (CloneNotSupportedException t2){  
             //捕获异常类型为T2的异常   
          } catch (ServerCloneException t3){  
            //捕获异常类型为T3的异常   
          }  finally{
//最后处理实现,不管异常是否捕获都会执行的代码
}
后两级catch子句永远都不会被执行,因为第一级永远会优先于后两级匹配,所以要按异常类型级别从低到高的顺序排放catch子句,即ServerCloneException 、CloneNotSupportedException 、Exception

JAVA异常体系详解_第5张图片

4、finally块也不是肯定会执行的,以下情况不会执行:

  • finally里发生异常时,finally执行中断

  • 在try或者catch里执行了System.exit(),finally也不会再执行了

  • 由于服务器硬件资源引起的线程死亡也会导致finally不能执行

5、抛出异常 throws throw

(1)throws

  • java代码抛出异常使用throw (任何java代码都可以抛出)

  • 方法抛出异常使用throws ,且可以同时抛出多个异常

  • 异常可以不断向上抛出,直到最后一层调用方法,即最后一层调用方法必须处理,否则发生错误

  • 方法覆盖,覆盖方法抛出的异常类型必须是被覆盖方法所声明异常的同类或子类,例如接口声明方法是IndexOutOfBoundsException,而实现类汇总覆盖方法抛出的异常类型为Exception,此时程序编译报错

JAVA异常体系详解_第6张图片

(2)throw

  • 在java代码中以throw 抛出Throwable类型的异常实例对象

  • throw 一旦执行,该方法体立即停止运行(throw后面的代码不会再执行了)

  • throw 抛出异常类型后,本方法的catch子句或上层各级调用方法的catch子句开始匹配该异常类型,直到匹配成功后,开始执行catch子句代码实现,如果没有匹配到合适的catch子句,最后交由JVM处理,打印异常信息且导致该线程停止工作

JAVA异常体系详解_第7张图片

你可能感兴趣的:(JAVA)