Java异常处理详解

1. 异常的定义与体系结构

异常是程序运行过程中出现的非正常情况,会中断程序的正常执行流程。Java异常体系结构如下图所示:

Throwable
├── Error(系统级错误,如内存溢出)
└── Exception(可处理异常)
    ├── RuntimeException(运行时异常,如空指针)
    └── 其他编译时异常(如IOException)

2. 异常的作用

  1. 调试辅助:通过异常信息快速定位问题根源

    Exception in thread "main" java.lang.NullPointerException: 
    Cannot invoke "String.length()" because "str" is null
  2. 流程控制:作为特殊返回值传递错误状态

    public void processFile() throws IOException {
        // 文件处理逻辑
    }

3. 异常处理方式

3.1 JVM默认处理

  • 打印异常信息(名称、原因、位置)

  • 终止程序运行

  • 示例现象

    Exception in thread "main" java.lang.ArithmeticException: / by zero
    at Main.main(Main.java:5)

3.2 try-catch捕获处理

基础语法

try {
    // 可能抛出异常的代码
} catch (ExceptionType1 e1) {
    // 处理类型1异常
} catch (ExceptionType2 e2) {
    // 处理类型2异常
} finally {
    // 无论是否异常都会执行
}

关键要点

  • 多catch块顺序:子类异常在前,父类在后

  • JDK7+多异常捕获:

    try {
        // code
    } catch (IOException | SQLException e) {
        e.printStackTrace();
    }
  • finally块常用于资源释放

完整示例

FileInputStream fis = null;
try {
    fis = new FileInputStream("test.txt");
    // 文件操作...
} catch (FileNotFoundException e) {
    System.out.println("文件未找到: " + e.getMessage());
} finally {
    if(fis != null) {
        try { fis.close(); } 
        catch (IOException e) { /* 处理关闭异常 */ }
    }
}

3.3 throws/throw抛出异常

关键字位置作用
throws方法声明声明可能抛出的异常类型
throw方法体内主动抛出异常对象

throws示例

public void readFile() throws IOException {
    // 可能抛出IO异常的代码
}

throw示例

public void setAge(int age) {
    if(age < 0) {
        throw new IllegalArgumentException("年龄不能为负数");
    }
    this.age = age;
}

编译时异常 vs 运行时异常

  • 编译时异常:必须处理(捕获或声明抛出)

  • 运行时异常:通常由程序逻辑错误引起,可不处理


4. Throwable类核心方法

方法输出示例说明
getMessage()"/ by zero"异常详细信息
toString()"java.lang.ArithmeticException: / by zero"简短描述
printStackTrace()完整堆栈跟踪信息输出到标准错误流

示例使用

try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println(e.getMessage());  // / by zero
    System.out.println(e.toString());    // java.lang.ArithmeticException: / by zero
    e.printStackTrace();                 // 完整堆栈信息
}

5. 自定义异常

实现步骤

  1. 继承Exception(编译时异常)或RuntimeException(运行时异常)

  2. 添加构造方法

示例代码

ublic class InvalidAgeException extends RuntimeException {
    // 无参构造
    public InvalidAgeException() {
        super("年龄无效异常");
    }
    
    // 带参构造
    public InvalidAgeException(String message) {
        super(message);
    }
}

// 使用示例
public class Person {
    private int age;
    
    public void setAge(int age) {
        if(age < 0 || age > 150) {
            throw new InvalidAgeException("无效年龄值: " + age);
        }
        this.age = age;
    }
}

6. 异常处理最佳实践

  1. 精准捕获:避免捕获过于宽泛的Exception

  2. 资源管理:优先使用try-with-resources

    try (FileInputStream fis = new FileInputStream("file.txt")) {
        // 自动资源管理
    } catch (IOException e) {
        // 异常处理
    }
  3. 异常包装:保留原始异常信息

    catch (SQLException e) {
        throw new ServiceException("数据库操作失败", e);
    }
  4. 日志记录:使用日志框架代替printStackTrace()

  5. 避免空catch块:至少要记录异常信息


通过系统学习异常处理机制,开发者可以编写出更健壮、易维护的Java程序。正确处理异常不仅能提升系统稳定性,还能显著提高调试效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值