1 异常划分
异常超类Throwable,他包含两大子类:Error和Exception。
Error(错误):一般代表JVM本身的错误,错误不能被程序代码所处理,比如OutOfMemoryError。
Exception(异常):程序本身可以捕获并且可以处理的异常。
异常也分为两类:运行时异常和编译异常。
运行时异常:RuntimeException及其子类,属于未检查异常(unchecked exception),在程序运行期间可能出现的错误,比如空指针(NullPointerException)、数组下标越界(ArrayIndexOutBoundException),一般由程序逻辑错误照成。
编译异常:除RuntimeException及其子类之外的异常。属于检查异常(checked exception),必须在编译前进行处理,如IOException。
注:Error也属于未检查异常(unchecked exception)。
2 异常处理
处理机制分为:捕获异常和抛出异常
捕获异常:
try {
//可能产生的异常的代码区
}catch (ExceptionType1 e) {
//捕获并处理try抛出异常类型为ExceptionType1的异常
}catch (ExceptionType2 e){
//捕获并处理try抛出异常类型为ExceptionType2的异常
}finally{
//无论是出现异常,finally块中的代码都将被执行
}
try代码块:用于捕获异常。其后可以接零个或者多个catch块。如果没有catch块,后必须跟finally块,来完成资源释放等操作,另外建议不要在finally中使用return,不用尝试通过catch来控制代码流程。
catch代码块:用于捕获异常,并在其中处理异常。
finally代码块:无论是否捕获异常,finally代码总会被执行。如果try代码块或者catch代码块中有return语句时,finally代码块将在方法返回前被执行。注意以下几种情况,finally代码块不会被执行完成:
1、 程序退出,或线程死亡
2、 finally代码块中的操作产生异常
注:finally中如果有抛出异常,或者有返回值,都将覆盖之前的异常或返回值。
抛出异常:
1、throws:方法声明时使用,使用样例:methodName throws SomeException(){}
2、throw:方法内部使用,使用样例:throw new SomeException();
3 异常转义
将一种类型的异常转成另一种类型的异常,然后再抛出异常。
通常在实际应用中,会自定义运行时异常,来对程序中出现的异常进行封装,在自定义异常中,可以使用模板方法,来对异常添加某些自定义的处理。比如某类自定义异常,可以单独在输出到某些文件中,便于分析。
/**
* CRPC统一运行时异常
*
* @author chaozai
* @date 2019年2月18日
*
*/
public class CRpcException extends RuntimeException {
private static final long serialVersionUID = 7790299052328666775L;
public CRpcException() {
super();
}
public CRpcException(String msg) {
super(msg);
}
public CRpcException(String msg, Throwable cause) {
super(msg, cause);
}
public CRpcException(Throwable cause) {
super(cause);
}
}
一般来说自定义异常包含:
- 一个无参构造函数
- 一个带有String参数的构造函数,并传递给父类的构造函数。
- 一个带有String参数和Throwable参数,并都传递给父类构造函数
- 一个带有Throwable 参数的构造函数,并传递给父类的构造函数
4 其他知识点
1、父类有方法声明抛出异常,即throws Exception,子类继承时,也同样抛出异常,此时,父类的异常同样要包含子类异常。可以自己思考下,虽然编译器会替我们检查,但是为啥这么设计呢?关键字:多态。
2、Java的异常是线程独立的,一般来说,如果出现未处理异常,则仅仅会导致当前线程终止,不会影响其他线程。错误Error另说哟。
爱家人,爱生活,爱设计,爱编程,拥抱精彩人生!