一、异常体系总结构
 
顶层父类:Throwable(所有错误、异常的父类)。

 Error:系统级严重错误,代码无法处理,常见:栈溢出、内存溢出。

Exception:程序可处理异常,分为两类:

1. RuntimeException运行时异常:编译无报错,运行时抛出,可选择性处理。

2. 非运行时检查异常:编译器强制捕获/抛出,否则编译失败。
 
常见运行时异常
 
NullPointerException(空指针异常)、ArrayIndexOutOfBounds(下标越界异常)、NumberFormatException(数字转换异常)、ClassCastException(类型强转异常)。
 
二、异常处理两种方案
 
方案1:throws 消极抛出异常
 
书写位置:方法声明后方。

作用:向外层调用方推卸异常处理责任。

特点:仅抛出不处理,程序最终仍会终止;父类异常可统一代理所有子类异常。
 
方案2:try-catch-finally 积极捕获异常
 
标准语法结构

try{
    // 可能出现异常的业务代码
}catch(NullPointerException e){
    // 精准捕获空指针异常并处理
}catch(Exception e){
    // 兜底捕获所有未知异常
}finally{
    // 无论是否报错、是否return,必然执行;用于关闭IO、数据库资源
}

核心注意事项
 
1. 多catch结构:子类异常必须写在父类异常之前。

2. finally块禁止编写return语句,会覆盖原有方法返回值。
 
三、手动抛出异常 throw
 
书写位置:方法内部。

作用:主动触发异常,中断程序执行。

 标准语法: throw new 异常类("自定义异常提示信息"); 
 
四、自定义异常
 
继承Exception:属于检查异常,调用方必须强制处理。

继承RuntimeException:属于运行时异常,无需强制捕获。

规范要求:自定义异常必须提供无参构造、带字符串参数构造方法。
 
自定义异常代码示例

// 自定义年龄非法异常
public class AgeException extends RuntimeException{
    // 无参构造
    public AgeException(){}
    // 带异常信息构造
    public AgeException(String msg){
        super(msg);
    }
}

五、方法重写异常规则
 
子类重写父类方法时:
 
1. 不能抛出比父类范围更大、数量更多的检查异常。

2. 父方法无异常时,子类禁止抛出检查异常。

更多推荐