异常的概念
Error:指正常情况下,不大可能出现的情况,绝大部分的Error都会导致程序(比如JVM自身)处于非正常状态,不可恢复状态。即程序运行终止。既然是非正常情况,所以不便于也不需要捕获。常见的比如OutOfMemoryError之类,都是Error的子类。
Exception:程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应的处理。
- 非RuntimeException:在程序没启动(运行)时,就会报错的异常(即:编译时报错的)
- RuntimeException:编码过程中不会报错,当启动程序时,控制台报错抛异常的就是RuntimeException
异常的处理
1、try,catch
- 非RuntimeException:需要用try,catch ----- 捕获并就地处理
try {
//TODO 可能出现的 非RuntimeException 的代码
} catch (AException e) {
//TODO 处理try中的 非RuntimeException
} catch (BException e){
//TODO 处理try中的 非RuntimeException
} catch (CException e) {
//TODO 处理try中的 非RuntimeException
}
...
} catch (Exception e) {
//TODO 处理try中的 非RuntimeException
}
- RuntimeException:需要写代码进行处理。如:空指针异常,则需要判空
注:为什么不用 try,catch 捕获 RuntimeException? 【即:为什么区分 RuntimeException 和 非RuntimeException】
因为RuntimeException出现的次数频繁。如:除数是0、空指针、数组下标越界等,其产生频繁,处理麻烦,若显示申明或者捕获将会对程序的可读性和运行效率影响很大。
RuntimeException:是代码的逻辑有问题或不完善(空指针、数组越界)造成的异常,这种问题应该通过修改代码的方式去处理。而不是使用 try catch去捕获
2、throws
A使用throws修饰的方法,如果调用者不打算处理此异常,可以继续通过throws声明异常,让上一级调用者处理异常。main()方法声明的异常将由Java虚拟机来处理
异常处理的底线是必须在返回客户前(Controller)捕获,RunTimeException随时可能发生,因此,每个controller的方法都应该try-catch,很麻烦,所以考虑切面,使用AOP切整个controller层。(统一的地方做统一的事)
3、自定义异常
继承RunTimeException
为什么自定义异常要继承 RunTimeException:
如果自定义异常(BusinessException)继承了 非RunTimeException(也就是Exception),则throw 该BusinessException的 方法(A)需要自己处理该可能出现的异常(try-catch 或 throws),如果 A使用了 throws 抛出了该异常,那么调用 A 方法的该方法B也需要 处理该异常.........以此类推,,如果A方法之上有很多方法,那么这些之上的方法都需要需要通过 throws 处理异常,所以,很麻烦,很啰嗦。所以自定义异常通常继承自RunTimeException。