Java异常体系全解析

异常体系概述​

Java 中的所有异常类型都是Throwable类的子类。异常体系分为两大主要分支:​

  • Error:表示程序无法处理的严重问题
  • Exception:表示程序可以处理的异常情况

Exception 又进一步分为:​

  • Checked Exception(受检异常):编译器强制要求处理
  • RuntimeException(运行时异常):编译器不强制处理

Throwable 根类​

java.lang.Throwable是所有异常和错误的根类,定义了以下核心方法:​

Error(严重错误)​

Error及其子类代表应用程序无法处理的严重问题,通常由 JVM 或底层系统引起。​

主要 Error 类型​

  1. VirtualMachineError​

虚拟机错误,JVM 内部错误​

子类:​

  • OutOfMemoryError

// 当JVM无法分配足够内存时抛出​

throw new OutOfMemoryError("Java heap space");​

  • StackOverflowError

// 当方法调用栈深度超过JVM限制时抛出(如无限递归)​

public void infiniteRecursion() {​

infiniteRecursion(); // 会抛出StackOverflowError​

}​

  • InternalError

// JVM内部错误​

throw new InternalError("Internal VM error");​

  1. LinkageError​

链接错误,类依赖关系问题​

子类:​

  • NoClassDefFoundError

// 编译时存在类,但运行时无法找到.class文件​

Class.forName("com.example.MissingClass"); // 可能抛出​

  • NoSuchMethodError

// 调用不存在的方法​

object.missingMethod(); // 运行时抛出​

  • NoSuchFieldError

// 访问不存在的字段​

object.missingField; // 运行时抛出​

  • UnsatisfiedLinkError

// 找不到native方法的本机语言定义​

System.loadLibrary("missingLibrary"); // 可能抛出​

  1. ClassFormatError​

类格式错误​

子类:​

  • UnsupportedClassVersionError

// 类文件版本不被当前JVM支持​

// 例如用Java 17编译的类在Java 8上运行​

  1. ThreadDeath​

线程结束错误​

// 当调用Thread.stop()时抛出​

Thread.currentThread().stop();​

Exception(异常)​

Exception及其子类代表程序可以处理的异常情况。​

主要 Exception 类型​

  1. IOException​

输入输出异常,处理文件、流操作时的错误​

子类:​

  • FileNotFoundException

// 文件未找到​

new FileInputStream("missingfile.txt"); // 必须处理​

  • EOFException

// 文件提前结束​

inputStream.read(); // 可能抛出​

  • SocketException

// 套接字操作异常​

socket.connect(new InetSocketAddress("host", port)); // 可能抛

  • MalformedURLException

// URL格式错误​

new URL("invalid-url"); // 必须处理​

  1. SQLException​

数据库访问异常​

// 数据库操作错误​

Connection conn = DriverManager.getConnection(url); // 必须处理​

Statement stmt = conn.createStatement();​

ResultSet rs = stmt.executeQuery(sql); // 可能抛出​

  1. ClassNotFoundException​

类未找到异常​

// 动态加载类时无法找到​

Class.forName("com.example.MissingClass"); // 必须处理​

  1. InterruptedException​

线程中断异常

// 线程在休眠或等待时被中断​

try {​

Thread.sleep(1000);​

} catch (InterruptedException e) {​

Thread.currentThread().interrupt(); // 重新设置中断状态​

}​

  1. CloneNotSupportedException​

克隆不支持异常​

// 调用clone()但类未实现Cloneable接口​

object.clone(); // 必须处理​

  1. IllegalAccessException​

非法访问异常​

// 访问不允许访问的类或成员​

field.setAccessible(true);​

field.get(object); // 可能抛出​

  1. InstantiationException​

实例化异常​

// 无法实例化类(如抽象类、接口)​

Class.forName("com.example.AbstractClass").newInstance(); // 必须处理​

Checked Exception(受检异常)​

编译器强制要求处理的异常,必须使用try-catch捕获或throws声明。​

完整 Checked Exception 列表​

  1. java.io 包​
  • IOException
  • FileNotFoundException
  • EOFException
  • SocketException
  • MalformedURLException
  • UnsupportedEncodingException
  • FileAlreadyExistsException
  1. java.sql 包​
  • SQLException
  • SQLTimeoutException
  • BatchUpdateException
  1. java.net包​
  • SocketException
  • BindException
  • ConnectException
  • UnknownHostException
  1. java.lang 包​
  • ClassNotFoundException
  • CloneNotSupportedException
  • IllegalAccessException
  • InstantiationException
  • InterruptedException
  • NoSuchFieldException
  • NoSuchMethodException
  1. java.util 包​
  • ParseException
  • IllegalFormatException
  • MissingResourceException
  1. java.security 包​
  • GeneralSecurityException
  • NoSuchAlgorithmException
  • InvalidKeyException

RuntimeException(运行时异常)​

编译器不强制处理的异常,通常由程序逻辑错误引起。​

主要 RuntimeException 类型​

  1. NullPointerException​

空指针异常​

// 调用null对象的方法或访问字段​

String s = null;​

s.length(); // 抛出NullPointerException​

  1. ArrayIndexOutOfBoundsException​

数组下标越界异常​

// 访问数组时使用无效索引​

int[] arr = new int[5];​

arr[10] = 1; // 抛出ArrayIndexOutOfBoundsException​

  1. ClassCastException​

类型转换异常​

// 强制类型转换失败​

Object obj = "string";​

Integer num = (Integer) obj; // 抛出ClassCastException​

  1. IllegalArgumentException​

非法参数异常​

// 方法接收到不合法的参数​

public void setAge(int age) {​

if (age < 0) {​

throw new IllegalArgumentException("Age cannot be negative");​

}​

}​

  1. ArithmeticException​

算术异常​

// 算术运算错误​

int result = 10 / 0; // 抛出ArithmeticException​

  1. NumberFormatException​

数字格式转换异常​

// 字符串转换为数字失败​

Integer.parseInt("abc"); // 抛出NumberFormatException​

  1. IndexOutOfBoundsException​

索引越界异常​

// 访问集合时使用无效索引​

List<String> list = new ArrayList<>();​

list.get(0); // 抛出IndexOutOfBoundsException​

  1. UnsupportedOperationException​

不支持的操作异常​

// 调用不支持的方法​

List<String> unmodifiableList = Collections.unmodifiableList(new ArrayList<>());​

unmodifiableList.add("element"); // 抛出UnsupportedOperationException​

完整 RuntimeException 列表​

  1. java.lang 包​
  • NullPointerException
  • ArrayIndexOutOfBoundsException
  • ClassCastException
  • IllegalArgumentException
  • ArithmeticException
  • NumberFormatException
  • IndexOutOfBoundsException
  • UnsupportedOperationException
  • IllegalStateException
  • NoSuchElementException
  • ConcurrentModificationException
  1. java.util 包​
  • IllegalFormatConversionException
  • InputMismatchException
  • NoSuchElementException
  • ConcurrentModificationException
  1. java.util.regex 包​
  • PatternSyntaxException
  1. java.net包​
  • IllegalArgumentException(在某些情况下)

异常处理最佳实践​

  1. 异常处理原则​

应该做的:​

  • 及时处理异常:对 Checked Exception 进行适当处理
  • 提供有意义的信息:异常信息应该清晰、具体
  • 记录异常日志:便于问题诊断和调试
  • 在合适的层级处理:在能够有效处理的层级捕获异常
  • 清理资源:使用 try-with-resources 确保资源释放

不应该做的:​

  • 忽略异常:避免空的 catch 块
  • 捕获所有异常:避免使用catch (Exception e)
  • 在 finally 块中返回值:可能覆盖异常信息
  • 过度使用异常:不要用异常控制正常流程
  • 不记录异常信息:难以诊断问题
  1. 异常处理模式​

Try-With-Resources​

// 自动关闭资源​

try (FileInputStream fis = new FileInputStream("file.txt");​

BufferedReader br = new BufferedReader(new InputStreamReader(fis))) {​

String line;​

while ((line = br.readLine()) != null) {​

System.out.println(line);​

}​

} catch (IOException e) {​

logger.error("Error reading file", e);​

throw new CustomException("Failed to read file", e);​

}​

多层异常处理​

public void businessOperation() throws BusinessException {​

try {​

dataAccessOperation();​

} catch (SQLException e) {​

logger.error("Database operation failed", e);​

throw new BusinessException("Data access error", e);​

}​

}​

private void dataAccessOperation() throws SQLException {​

// 数据库操作​

}​

自定义异常​

//自定义业务异常​

public class BusinessException extends Exception {​

private final String errorCode;​

public BusinessException(String message, String errorCode) {​

super(message);​

this.errorCode = errorCode;​

}​

public BusinessException(String message, String errorCode, Throwable cause) {​

super(message, cause);​

this.errorCode = errorCode;​

}​

public String getErrorCode() {​

return errorCode;​

}​

}​

  1. 异常链处理​

try {​

// 操作1​

operation1();​

} catch (Exception e) {​

// 记录异常​

logger.error("Operation 1 failed", e);​

// 包装为新异常并重新抛出​

throw new BusinessException("Operation failed", e);​

}​

异常分类对比表​

|-------|--------------------|------------------------|-------------------------------------------|
| 特性​ | Error​ | Checked Exception​ | RuntimeException​ |
| 继承关系​ | Throwable → Error​ | Throwable → Exception​ | Throwable → Exception → RuntimeException​ |
| 处理要求​ | 否(编译器不要求)​ | 是(必须处理)​ | 否(编译器不要求)​ |
| 可恢复性​ | 严重,通常不可恢复​ | 可恢复​ | 通常不可恢复​ |
| 常见来源​ | JVM 或系统环境​ | 外部因素(文件、网络等)​ | 程序逻辑错误​ |
| 处理方式​ | 调整系统 / JVM 参数​ | try-catch 或 throws​ | 修复代码逻辑​ |
| 示例​ | OutOfMemoryError​ | IOException​ | NullPointerException​ |
| 发生时机​ | 运行时​ | 编译时检查,运行时发生​ | 运行时​ |

异常处理决策表​

|--------------------|------------|------------|
| 异常类型​ | 建议处理方式​ | 示例场景​ |
| Error​ | 监控和报警​ | 内存溢出、栈溢出​ |
| Checked Exception​ | 立即处理或向上传递​ | 文件操作、网络连接​ |
| RuntimeException​ | 修复代码逻辑​ | 空指针、数组越界​ |

总结​

Java 异常体系是确保程序健壮性的重要机制:​

  1. Error:表示严重的系统级错误,程序通常无法恢复
  1. Checked Exception:表示可预见的外部问题,必须显式处理
  1. RuntimeException:表示程序逻辑错误,应该通过代码修复避免

最佳实践建议:​

  • 合理使用异常处理,不要过度使用
  • 提供清晰的异常信息和完整的堆栈跟踪
  • 优先修复 RuntimeException 的根本原因
  • 对 Checked Exception 提供优雅的恢复机制
  • 使用自定义异常封装业务逻辑错误
  • 利用 try-with-resources 确保资源安全释放

通过理解和正确使用 Java 异常体系,可以编写出更加健壮、可维护的 Java 应用程序。

相关推荐
v***88561 小时前
Springboot项目:使用MockMvc测试get和post接口(含单个和多个请求参数场景)
java·spring boot·后端
q***49451 小时前
Ubuntu介绍、与centos的区别、基于VMware安装Ubuntu Server 22.04、配置远程连接、安装jdk+Tomcat
java·ubuntu·centos
q***72191 小时前
PHP使用Redis实战实录2:Redis扩展方法和PHP连接Redis的多种方案
开发语言·redis·php
k***82511 小时前
python爬虫——爬取全年天气数据并做可视化分析
开发语言·爬虫·python
IMPYLH1 小时前
Lua 的 require 函数
java·开发语言·笔记·后端·junit·lua
曾经的三心草1 小时前
基于正倒排索引的Java文档搜索引擎1-实现索引模块-实现Parser类
java·开发语言·搜索引擎
q***01652 小时前
Python爬虫完整代码拿走不谢
开发语言·爬虫·python
vx_bscxy3222 小时前
告别毕设焦虑!Python 爬虫 + Java 系统 + 数据大屏,含详细开发文档 基于web的图书管理系统74010 (上万套实战教程,赠送源码)
java·前端·课程设计
顺心而行...2 小时前
一些问题记录
开发语言