Java 异常处理是程序出错时的容错机制,用来避免程序直接崩溃,让代码更健壮、易维护。

我用最通俗、最实用的方式给你讲透,新手也能直接看懂、直接用。


一、什么是异常?

异常就是程序运行时出现的错误 / 意外情况,比如:

  • 数组下标越界
  • 空指针访问
  • 除数为 0
  • 文件找不到
  • 网络断开

Java 把所有异常都封装成了对象,统一管理。


二、异常的分类(必须记住)

Java 异常继承树:

plaintext

Throwable
  ├─ Error(错误,JVM 级,代码管不了)
  └─ Exception(异常,代码可以处理)
       ├─ 运行时异常 RuntimeException(非检查异常)
       └─ 编译时异常(检查异常,必须处理)

1. Error(错误)

JVM 内部问题,代码无法处理,比如:

  • 内存溢出 OOM
  • 栈溢出 StackOverflowError不用 try-catch,处理也没用。

2. 运行时异常(非检查)

代码逻辑错误导致,编译不强制要求处理,比如:

  • NullPointerException 空指针
  • ArrayIndexOutOfBoundsException 数组越界
  • ArithmeticException 算术异常(除 0)
  • ClassCastException 类型转换异常

3. 编译时异常(检查)

编译期强制要求处理,否则代码无法运行,比如:

  • IOException 文件读写异常
  • SQLException 数据库异常
  • FileNotFoundException 文件找不到

三、异常处理 5 大关键字

trycatchfinallythrowthrows

1. 最基础结构:try-catch

java

运行

public class Test {
    public static void main(String[] args) {
        try {
            // 可能出错的代码放这里
            int a = 10 / 0; // 这里会抛算术异常
            System.out.println("这句不会执行");
        } catch (ArithmeticException e) {
            // 捕获到异常后执行
            System.out.println("出错了:除数不能为0");
            // 打印异常详细信息(开发常用)
            e.printStackTrace();
        }
        System.out.println("程序继续运行~");
    }
}

2. finally:无论是否异常,一定执行

常用于资源释放:关闭文件、关闭连接、关闭流。

java

运行

try {
    // 危险代码
} catch (Exception e) {
    // 处理异常
} finally {
    // 必执行
    System.out.println("finally 始终运行");
}

3. 多个 catch(按从小到大捕获)

java

运行

try {
    // ...
} catch (NullPointerException e) {
    // 精确捕获
} catch (ArrayIndexOutOfBoundsException e) {
    // 精确捕获
} catch (Exception e) {
    // 捕获所有其他异常(必须放最后)
}

四、手动抛出异常:throw

你可以主动抛出异常,用于校验参数、业务判断。

java

运行

public void checkAge(int age) {
    if (age < 0) {
        // 手动抛出异常
        throw new IllegalArgumentException("年龄不能为负数");
    }
}

五、方法声明异常:throws

把异常抛给调用者处理,自己不处理。

java

运行

// 告诉调用者:我可能抛出 IO 异常
public void readFile() throws IOException {
    // 读文件代码
}

六、自定义异常(工作常用)

可以根据业务创建自己的异常,比如登录异常、订单异常。

步骤:

  1. 继承 Exception(检查异常)
  2. 或继承 RuntimeException(运行时异常)

java

运行

// 自定义登录异常
public class LoginException extends RuntimeException {
    public LoginException(String message) {
        super(message);
    }
}

// 使用
public void login(String username) {
    if (username == null || username.isEmpty()) {
        throw new LoginException("用户名不能为空");
    }
}

七、异常处理最佳实践

  1. 不要捕获大型异常:别随便写 catch (Exception e),尽量精确捕获
  2. 不要生吞异常:捕获后至少打印日志,不要空着 {}
  3. finally 释放资源:文件、数据库、网络连接必须关
  4. 自定义异常更清晰:业务代码优先用自定义异常
  5. 运行时异常不用强制捕获,编译时异常必须捕获或抛出
  6. 异常只用于错误处理,不要用来控制业务流程

八、一句话总结

  • try:放可能出错的代码
  • catch:捕获并处理异常
  • finally:必须执行,用于释放资源
  • throw:手动抛异常
  • throws:方法声明异常,交给上层处理

总结

  1. 异常分 Error、运行时异常、编译时异常
  2. 核心语法:try-catch-finally
  3. 手动抛异常用 throw,方法声明用 throws
  4. 业务开发可以自定义异常,让代码更清晰
  5. 异常处理的目的:程序不崩溃、错误可追踪
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐