# Java 异常处理
异常处理是Java程序设计中的重要组成部分,用于处理程序运行时可能出现的错误情况。
# 异常体系
# 异常层次结构
Throwable
├── Error(错误)
│ ├── OutOfMemoryError
│ ├── StackOverflowError
│ └── ...
└── Exception(异常)
├── RuntimeException(运行时异常)
│ ├── NullPointerException
│ ├── ArrayIndexOutOfBoundsException
│ ├── ClassCastException
│ └── ...
└── 其他异常
├── IOException
├── SQLException
└── ...
# 异常处理机制
# try-catch-finally
try {
// 可能抛出异常的代码
int result = 10 / 0;
} catch (ArithmeticException e) {
// 处理特定类型的异常
System.out.println("除数不能为零:" + e.getMessage());
} catch (Exception e) {
// 处理其他类型的异常
System.out.println("发生异常:" + e.getMessage());
} finally {
// 无论是否发生异常都会执行的代码
System.out.println("清理资源");
}
# 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) {
e.printStackTrace();
}
# 抛出异常
# throws关键字
public void readFile(String filename) throws IOException {
FileReader reader = new FileReader(filename);
// 读取文件操作
}
# throw关键字
public void validateAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数");
}
}
# 自定义异常
// 自定义检查异常
public class CustomCheckedException extends Exception {
public CustomCheckedException(String message) {
super(message);
}
}
// 自定义运行时异常
public class CustomRuntimeException extends RuntimeException {
public CustomRuntimeException(String message) {
super(message);
}
}
# 异常处理最佳实践
- 只捕获可以处理的异常
- 在合适的层级处理异常
- 提供有意义的错误信息
- 正确使用finally块清理资源
- 优先使用try-with-resources语句
// 示例:银行转账
public class BankAccount {
private double balance;
private String accountNumber;
public void transfer(BankAccount target, double amount) throws InsufficientFundsException {
try {
if (amount <= 0) {
throw new IllegalArgumentException("转账金额必须大于0");
}
if (balance < amount) {
throw new InsufficientFundsException("余额不足");
}
balance -= amount;
target.deposit(amount);
} catch (IllegalArgumentException e) {
// 记录日志
throw e; // 重新抛出异常
}
}
public void deposit(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("存款金额必须大于0");
}
balance += amount;
}
}
class InsufficientFundsException extends Exception {
public InsufficientFundsException(String message) {
super(message);
}
}
# 练习
- 实现一个文件复制程序,正确处理可能的IO异常
- 创建一个简单的计算器,处理各种可能的输入错误
- 设计一个用户注册系统,包含自定义的验证异常
# 高级特性
# 异常链
// 异常链示例
public class ExceptionChainDemo {
public void processData() throws DataProcessException {
try {
readData();
} catch (IOException e) {
// 创建新异常,保留原始异常信息
throw new DataProcessException("数据处理失败", e);
}
}
private void readData() throws IOException {
throw new IOException("读取文件失败");
}
}
class DataProcessException extends Exception {
public DataProcessException(String message, Throwable cause) {
super(message, cause);
}
}
# 多异常捕获
// Java 7+ 多异常捕获
try {
Path path = Paths.get("file.txt");
String content = Files.readString(path);
JSONParser parser = new JSONParser();
parser.parse(content);
} catch (IOException | ParseException e) {
logger.error("文件处理失败", e);
}
# 异常性能优化
// 异常处理性能优化示例
public class ExceptionPerformance {
private static final Logger logger = LoggerFactory.getLogger(ExceptionPerformance.class);
// 不推荐:使用异常控制程序流程
public boolean badPractice(String key, Map<String, String> map) {
try {
String value = map.get(key);
return value != null;
} catch (Exception e) {
return false;
}
}
// 推荐:使用正常的控制结构
public boolean goodPractice(String key, Map<String, String> map) {
if (map == null || key == null) {
return false;
}
return map.containsKey(key);
}
// 异常日志最佳实践
public void logException(Exception e) {
// 记录完整的异常栈信息
logger.error("操作失败: {}", e.getMessage(), e);
// 对于特定异常进行详细记录
if (e instanceof SQLException) {
SQLException sqlEx = (SQLException) e;
logger.error("SQL State: {}, Error Code: {}",
sqlEx.getSQLState(), sqlEx.getErrorCode());
}
}
}
# 自定义异常处理器
// 全局异常处理器示例
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleException(Exception e) {
logger.error("未处理的异常", e);
ErrorResponse error = new ErrorResponse(
HttpStatus.INTERNAL_SERVER_ERROR.value(),
"服务器内部错误",
e.getMessage()
);
return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(BusinessException.class)
public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException e) {
logger.warn("业务异常", e);
ErrorResponse error = new ErrorResponse(
HttpStatus.BAD_REQUEST.value(),
"业务处理失败",
e.getMessage()
);
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
}
@Data
@AllArgsConstructor
class ErrorResponse {
private int status;
private String error;
private String message;
}
# 异常处理设计模式
// 使用模板方法模式处理异常
public abstract class AbstractOperation<T> {
public final T execute() {
try {
validateInput();
T result = doExecute();
afterExecute(result);
return result;
} catch (ValidationException e) {
handleValidationError(e);
throw e;
} catch (Exception e) {
handleError(e);
throw new OperationException("操作执行失败", e);
}
}
protected abstract T doExecute() throws Exception;
protected abstract void validateInput() throws ValidationException;
protected void afterExecute(T result) {}
protected void handleValidationError(ValidationException e) {}
protected void handleError(Exception e) {}
}
// 实现示例
public class UserRegistration extends AbstractOperation<User> {
private final UserDTO userDTO;
private final UserService userService;
@Override
protected void validateInput() throws ValidationException {
if (userDTO.getUsername() == null || userDTO.getUsername().isEmpty()) {
throw new ValidationException("用户名不能为空");
}
}
@Override
protected User doExecute() throws Exception {
return userService.register(userDTO);
}
@Override
protected void handleValidationError(ValidationException e) {
logger.warn("用户注册验证失败: {}", e.getMessage());
}
}
这些高级特性能帮助你:
- 更好地追踪异常源头
- 优化异常处理性能
- 实现统一的异常处理机制
- 设计更健壮的异常处理架构
← Java 面向对象编程 Java 集合框架 →