mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
655 字
2 分钟
Java异常处理详解
2026-02-01

异常处理是Java开发里最基础也最容易忽视的东西了。刚学的时候觉得try-catch就是写个模板代码,后来项目上线了才知道——异常处理做不好,线上出问题连排查都无从下手。这篇文章把Java异常体系的来龙去脉讲清楚。

Java异常处理详解#

什么是异常?#

异常就是程序运行时出的问题,会中断正常执行流程。在Java中,异常就是一个对象。要注意,异常和Error是两回事——Error是程序自己搞不定的(比如内存溢出),而异常是我们可以处理的。

异常的分类#

受检异常(Checked Exception)#

编译器要求必须处理的异常,继承自Exception(不包括RuntimeException)。

常见的有:IOExceptionSQLExceptionClassNotFoundExceptionFileNotFoundException

不处理的话编译就过不了,所以必须用try-catch兜着或者在方法上throws。

非受检异常(Unchecked Exception / RuntimeException)#

编译器不强制处理的异常,继承自RuntimeException

常见的有:NullPointerExceptionArrayIndexOutOfBoundsExceptionArithmeticExceptionIllegalArgumentExceptionClassCastException

异常层次结构#

Throwable
├── Error ← 程序搞不定的,别catch
│ ├── OutOfMemoryError
│ └── StackOverflowError
└── Exception
├── RuntimeException ← 非受检,不用强制处理
└── IOException 等 ← 受检,必须处理

异常处理机制#

try-catch#

try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("算术异常:" + e.getMessage());
}

多个catch#

子类异常在前,父类在后:

try {
// ...
} catch (NullPointerException e) {
// 先捕获具体的
} catch (Exception e) {
// 再捕获通用的
}

finally#

无论是否发生异常,finally都会执行。用来释放资源(关闭文件、数据库连接等)。

try {
// ...
} catch (Exception e) {
// ...
} finally {
// 一定会执行
}

注意:finally里别用return,它会覆盖try/catch里的return值。

try-with-resources(Java 7+)#

实现了AutoCloseable接口的资源可以自动关闭,不用写finally了:

try (FileReader reader = new FileReader("file.txt")) {
// 读取文件
} catch (IOException e) {
// reader会自动关闭
}

throw 和 throws#

  • throw:手动抛出异常
  • throws:声明方法可能抛出的异常
public void checkAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数");
}
}
public void readFile(String path) throws IOException {
// ...
}

自定义异常#

继承Exception(受检)或RuntimeException(非受检):

public class BusinessException extends RuntimeException {
private int errorCode;
public BusinessException(int errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
public int getErrorCode() {
return errorCode;
}
}

常见陷阱#

  1. 捕获异常后什么都不做——这是最坑的,出了问题连日志都找不到
  2. 用异常做流程控制——比如用ArrayIndexOutOfBoundsException判断数组越界,性能差不说,代码也难看
  3. 在finally里return——会覆盖try/catch的返回值
  4. 不释放资源——打开文件流忘了关,服务器上文件描述符被耗尽,应用直接挂了。这个我犯过,教训深刻
  5. 丢失原始异常信息——捕获异常后抛新异常,忘了把原始异常传进去

💡 实战贴士: 用try-with-resources替代try-finally来管理资源,代码更简洁,还能避免忘记关闭资源的问题。另外,日志记录异常时用 logger.error("消息", e),别用 e.printStackTrace(),生产环境没人看控制台。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

部分信息可能已经过时

目录