目标:掌握 Java 异常的处理机制,编写健壮代码
一、理论知识
1. 异常的分类
-
检查异常(Checked Exception):
- 编译时异常,必须在代码中显式处理。
- 典型例子:
IOException
、SQLException
。
代码示例:文件读取中的检查异常
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class CheckedExceptionExample {
public static void readFile(String filePath) {
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.err.println("文件读取失败:" + e.getMessage());
}
}
public static void main(String[] args) {
readFile("nonexistent_file.txt"); // 模拟文件不存在的场景
}
}
-
运行时异常(Unchecked Exception):
- 运行时才会抛出,不强制要求显式处理。
- 典型例子:
NullPointerException
、ArrayIndexOutOfBoundsException
。
代码示例:除数为 0 的运行时异常
public class UncheckedExceptionExample {
public static int divide(int a, int b) {
if (b == 0) {
throw new ArithmeticException("除数不能为 0");
}
return a / b;
}
public static void main(String[] args) {
try {
int result = divide(10, 0);
System.out.println("结果:" + result);
} catch (ArithmeticException e) {
System.err.println("运行时异常:" + e.getMessage());
}
}
}
-
自定义异常:
- 自定义异常类,继承
Exception
- 自定义异常类,继承
代码示例:自定义业务异常
class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message);
}
}
public class CustomExceptionExample {
public static void checkAge(int age) throws InvalidAgeException {
if (age < 18) {
throw new InvalidAgeException("年龄必须大于或等于 18 岁");
}
System.out.println("年龄验证通过");
}
public static void main(String[] args) {
try {
checkAge(16);
} catch (InvalidAgeException e) {
System.err.println("自定义异常:" + e.getMessage());
}
}
}
二、异常处理机制
1. try-catch-finally
try
块:包含可能抛出异常的代码。catch
块:捕获并处理异常。finally
块:无论是否抛出异常,都会执行的代码。
代码示例:使用 finally 释放资源
import java.io.FileInputStream;
import java.io.IOException;
public class TryCatchFinallyExample {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("example.txt");
int data;
while ((data = fis.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
System.err.println("文件操作异常:" + e.getMessage());
} finally {
if (fis != null) {
try {
fis.close();
System.out.println("\n资源已释放");
} catch (IOException e) {
System.err.println("关闭文件流时发生错误:" + e.getMessage());
}
}
}
}
}
2. throws 与捕获异常的区别
throws
:声明方法可能抛出的异常,交由调用者处理。try-catch
:在方法内部处理异常。
代码示例:throws 和 try-catch 的使用
import java.io.IOException;
public class ThrowsExample {
public static void riskyOperation() throws IOException {
throw new IOException("模拟 IO 异常");
}
public static void safeOperation() {
try {
riskyOperation();
} catch (IOException e) {
System.err.println("异常已捕获:" + e.getMessage());
}
}
public static void main(String[] args) {
safeOperation(); // 异常在方法内部处理
}
}
三、使用场景
-
检查异常的场景:
- 文件操作(
IOException
)。 - 数据库访问(
SQLException
)。
- 文件操作(
-
运行时异常的场景:
- 避免空指针异常(
NullPointerException
)。 - 校验用户输入(如
ArrayIndexOutOfBoundsException
)。
- 避免空指针异常(
-
自定义异常的场景:
- 业务逻辑校验(如年龄、权限验证)。
- 统一处理业务层异常,提升代码可读性和维护性。
四、项目中的异常管理策略
-
日志记录:
- 使用日志框架(如
Log4j
、SLF4J
)记录异常信息,方便排查。
- 使用日志框架(如
-
统一异常处理:
- 在 Web 项目中,利用全局异常处理机制(如 Spring 的
@ControllerAdvice
)集中管理异常。
- 在 Web 项目中,利用全局异常处理机制(如 Spring 的
-
资源管理:
- 使用
try-with-resources
自动管理资源释放。
- 使用
class CustomResource implements AutoCloseable {
private String name;
public CustomResource(String name) {
this.name = name;
System.out.println(name + " 资源已打开");
}
public void performTask() {
System.out.println(name + " 正在执行任务");
}
@Override
public void close() {
System.out.println(name + " 资源已关闭");
}
}
public class CustomResourceExample {
public static void main(String[] args) {
try (CustomResource resource1 = new CustomResource("资源1");
CustomResource resource2 = new CustomResource("资源2")) {
resource1.performTask();
resource2.performTask();
} catch (Exception e) {
System.err.println("发生异常:" + e.getMessage());
}
}
}
说明:
- 自定义类实现了
AutoCloseable
接口。- 资源会在
try
块结束时自动关闭。
总结
在本次学习中,我们深入掌握了 Java 异常处理机制,理解了异常的分类和应用场景。检查异常(如 IOException
)需要在编译期处理,而运行时异常(如 NullPointerException
)可以在运行时避免或捕获。此外,自定义异常用于满足特定业务需求,有助于提升代码的可读性和维护性。通过 try-catch-finally
、throws
以及 try-with-resources
等技术,可以有效捕获、管理和记录异常。实际工作中,异常处理能提升系统的健壮性,并通过统一管理和日志记录来优化用户体验。