java中的异常

Java 中的异常处理机制是程序健壮性和容错性的重要保障。Java 异常体系基于 Throwable 类构建,分为 检查型异常(Checked Exceptions)非检查型异常(Unchecked Exceptions)。以下是 Java 异常的结构和处理方式的详细说明:


一、异常体系结构

1. Throwable

所有异常类的根类,是 ErrorException 的父类。

  • Error:表示 JVM 本身的严重问题,如 OutOfMemoryErrorStackOverflowError,通常应用程序无法处理。
  • Exception:表示程序运行中可能出现的异常,可以通过 try-catch 捕获处理。

2. Exception 的子类

  • Checked Exceptions(受检异常)

    • 编译器强制要求处理的异常,如 IOExceptionSQLException
    • 必须在代码中捕获或在方法签名中声明抛出(使用 throws)。
  • Unchecked Exceptions(非受检异常)

    • 继承自 RuntimeException,如 NullPointerExceptionArrayIndexOutOfBoundsException
    • 编译时不强制处理,运行时可能抛出。

二、异常处理机制

1. try-catch-finally 结构

java 复制代码
try {
    // 可能抛出异常的代码
} catch (ExceptionType1 e) {
    // 处理异常
} catch (ExceptionType2 e) {
    // 处理其他异常
} finally {
    // 总是执行,通常用于资源释放
}
  • try 块中执行可能抛出异常的代码。
  • catch 块按顺序匹配异常类型。
  • finally 块无论是否发生异常都会执行(除非 JVM 退出)。

2. throwthrows

  • throw:手动抛出一个异常对象。

    java 复制代码
    throw new IllegalArgumentException("参数错误");
  • throws:声明方法可能抛出的异常类型(用于受检异常)。

    java 复制代码
    public void readFile() throws IOException { ... }

三、自定义异常

Java 允许开发者定义自己的异常类,通常继承自 ExceptionRuntimeException

java 复制代码
public class MyCustomException extends Exception {
    public MyCustomException(String message) {
        super(message);
    }
}

使用示例:

java 复制代码
if (value < 0) {
    throw new MyCustomException("值不能为负数");
}

如果继承Exception实现自定义异常则需要手动处理异常,因为继承Exception实现的自定义异常数据受检异常,需要进行处理。如果继承RuntimeException实现的自定义异常,则不需要手动处理(提个问题:为什么RuntimeException明明继承了Exeption,为什么不需要处理?个人理解时jvm底层对继承了Exception和继承了RuntimeExeption分别做了不同的处理。)


四、常见异常类型

异常类名 描述
NullPointerException 访问空对象的属性或方法
ArrayIndexOutOfBoundsException 数组越界访问
ClassCastException 类型转换错误
IllegalArgumentException 方法接收到非法参数
IOException 输入输出异常,如文件读写失败
SQLException 数据库操作异常
InterruptedException 线程被中断

五、最佳实践

  1. 避免捕获所有异常(catch (Exception e):应具体捕获需要处理的异常类型。

  2. 不要忽略异常 :捕获后应记录日志或处理,而非空 catch 块。

  3. 使用 try-with-resources(Java 7+):自动关闭资源。

    java 复制代码
    try (FileInputStream fis = new FileInputStream("file.txt")) {
        // 读取文件
    } catch (IOException e) {
        e.printStackTrace();
    }
  4. 合理使用受检异常与非受检异常:受检异常适用于可恢复的情况,非受检异常用于程序错误。


六、总结

Java 异常机制提供了结构化、可维护的错误处理方式。理解异常的分类、处理流程和最佳实践,有助于编写更健壮、可维护的代码。

相关推荐
在雨季等你36 分钟前
奋斗在创业路上的老开发
android·前端·后端
转转技术团队43 分钟前
游戏账号大图生成
java·后端
程序员爱钓鱼1 小时前
Go语言实战案例-批量重命名文件
后端·google·go
大熊计算机1 小时前
大模型推理加速实战,vLLM 部署 Llama3 的量化与批处理优化指南
后端
程序员爱钓鱼1 小时前
Go语言实战案例-遍历目录下所有文件
后端·google·go
喵个咪1 小时前
WSL2下的Ubuntu 24.0突然apt update报错 Could not wait for server fd 的解决方案
后端
赵星星5201 小时前
Cursor如何解决循环依赖!看完太妙了!
后端
大熊计算机2 小时前
Redis 缓存穿透/雪崩实战防御,从本地缓存到分布式锁的立体方案
后端
00后程序员2 小时前
iOS WebView 调试实战 localStorage 与 sessionStorage 同步问题全流程排查
后端
bcbnb2 小时前
iOS加固工具有哪些?从零源码到深度混淆的全景解读
后端