本文目录导读:

我来系统地介绍Java异常处理的规范化流程和最佳实践。
异常处理的核心原则
异常分类
// Throwable 体系
Throwable
├── Error(不可处理,系统级错误)
│ ├── OutOfMemoryError
│ └── StackOverflowError
└── Exception(可处理)
├── Checked Exception(必须处理)
│ ├── IOException
│ ├── SQLException
│ └── ClassNotFoundException
└── Unchecked Exception(运行时异常)
├── NullPointerException
├── IllegalArgumentException
└── IndexOutOfBoundsException
标准异常处理模式
基础try-catch-finally
public class StandardExceptionHandling {
// 基本模式
public void basicHandling() {
try {
// 可能抛出异常的代码
riskyOperation();
} catch (SpecificException e) {
// 处理特定异常
log.error("特定异常发生", e);
throw new BusinessException("操作失败", e);
} catch (GeneralException e) {
// 处理通用异常
log.error("通用异常", e);
handleGracefully(e);
} finally {
// 清理资源(必须执行)
closeResources();
}
}
// Java 7+ try-with-resources
public void tryWithResources() {
try (Connection conn = getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {
while (rs.next()) {
processUser(rs);
}
} catch (SQLException e) {
log.error("数据库操作异常", e);
throw new DataAccessException("查询用户失败", e);
}
}
}
多层异常处理
public class MultiLayerExceptionHandling {
// Service层
public class UserService {
public User createUser(UserDTO dto) {
try {
validateUser(dto);
User user = convertToEntity(dto);
return userRepository.save(user);
} catch (ValidationException e) {
throw new BusinessException("用户数据验证失败", e);
} catch (DataAccessException e) {
throw new BusinessException("用户创建失败", e);
}
}
}
// Controller层
@RestController
public class UserController {
@PostMapping("/users")
public ResponseEntity<ApiResponse<User>> createUser(@RequestBody UserDTO dto) {
try {
User user = userService.createUser(dto);
return ResponseEntity.ok(ApiResponse.success(user));
} catch (BusinessException e) {
return ResponseEntity.badRequest()
.body(ApiResponse.error(e.getMessage()));
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error("系统异常"));
}
}
}
}
自定义异常体系
异常层次结构
// 基础业务异常
public abstract class BaseException extends RuntimeException {
private final String errorCode;
private final Object[] args;
public BaseException(String errorCode, String message, Object... args) {
super(message);
this.errorCode = errorCode;
this.args = args;
}
public BaseException(String errorCode, String message, Throwable cause) {
super(message, cause);
this.errorCode = errorCode;
this.args = new Object[0];
}
public String getErrorCode() {
return errorCode;
}
public Object[] getArgs() {
return args;
}
}
// 具体业务异常
public class UserNotFoundException extends BaseException {
public UserNotFoundException(Long userId) {
super("USER_001",
String.format("用户不存在: %d", userId),
userId);
}
}
public class InsufficientBalanceException extends BaseException {
public InsufficientBalanceException(Double balance, Double required) {
super("BALANCE_001",
String.format("余额不足: 当前%.2f, 需要%.2f", balance, required),
balance, required);
}
}
异常码枚举
public enum ErrorCode {
// 系统级错误
SYSTEM_ERROR("SYS_001", "系统异常"),
DATABASE_ERROR("SYS_002", "数据库异常"),
// 业务级错误
USER_NOT_FOUND("USER_001", "用户不存在"),
USER_ALREADY_EXISTS("USER_002", "用户已存在"),
INVALID_PARAMETER("PARAM_001", "参数验证失败"),
// 权限错误
UNAUTHORIZED("AUTH_001", "未授权"),
FORBIDDEN("AUTH_002", "无权限"),
TOKEN_EXPIRED("AUTH_003", "Token过期");
private final String code;
private final String message;
ErrorCode(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() { return code; }
public String getMessage() { return message; }
}
统一异常处理
Spring Boot全局异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException e) {
ErrorResponse response = ErrorResponse.builder()
.code(e.getErrorCode())
.message(e.getMessage())
.timestamp(LocalDateTime.now())
.build();
return ResponseEntity.badRequest().body(response);
}
@ExceptionHandler(ValidationException.class)
public ResponseEntity<ErrorResponse> handleValidationException(ValidationException e) {
ErrorResponse response = ErrorResponse.builder()
.code("VALIDATION_ERROR")
.message("参数验证失败")
.errors(e.getErrors())
.timestamp(LocalDateTime.now())
.build();
return ResponseEntity.badRequest().body(response);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleException(Exception e) {
log.error("未处理的异常", e);
ErrorResponse response = ErrorResponse.builder()
.code("SYSTEM_ERROR")
.message("系统异常,请联系管理员")
.timestamp(LocalDateTime.now())
.build();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(response);
}
// 参数校验异常
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidationExceptions(
MethodArgumentNotValidException ex) {
List<String> errors = ex.getBindingResult()
.getFieldErrors()
.stream()
.map(error -> error.getField() + ": " + error.getDefaultMessage())
.collect(Collectors.toList());
ErrorResponse response = ErrorResponse.builder()
.code("VALIDATION_ERROR")
.message("参数验证失败")
.errors(errors)
.timestamp(LocalDateTime.now())
.build();
return ResponseEntity.badRequest().body(response);
}
}
@Builder
@Data
public class ErrorResponse {
private String code;
private String message;
private List<String> errors;
private LocalDateTime timestamp;
}
资源管理最佳实践
使用try-with-resources
public class ResourceManagement {
// 自动关闭资源
public void processFile(String path) {
try (FileInputStream fis = new FileInputStream(path);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis))) {
String line;
while ((line = reader.readLine()) != null) {
processLine(line);
}
} catch (IOException e) {
log.error("文件处理异常", e);
throw new FileProcessingException("处理文件失败: " + path, e);
}
}
// 自定义资源
public class DatabaseResource implements AutoCloseable {
private Connection connection;
public DatabaseResource(Connection connection) {
this.connection = connection;
}
@Override
public void close() {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
log.error("关闭数据库连接失败", e);
}
}
}
}
}
异常日志规范
统一的日志记录
public class ExceptionLogging {
private static final Logger log = LoggerFactory.getLogger(ExceptionLogging.class);
public void handleWithLogging() {
try {
riskyOperation();
} catch (BusinessException e) {
// 记录业务异常
log.warn("业务异常: code={}, message={}, args={}",
e.getErrorCode(), e.getMessage(), e.getArgs());
// 重新包装后抛出
throw new ServiceException("处理失败", e);
} catch (DataAccessException e) {
// 记录数据访问异常(包含堆栈信息)
log.error("数据访问异常: {}", e.getMessage(), e);
// 转换为业务异常
throw new ServiceException("数据操作失败", e);
} catch (Exception e) {
// 记录未知异常
log.error("未预期的异常", e);
// 抛出系统异常
throw new SystemException("系统异常", e);
}
}
// 异常信息记录工具
public static String buildErrorMessage(Exception e) {
StringBuilder sb = new StringBuilder();
sb.append("异常类型: ").append(e.getClass().getName());
sb.append(", 消息: ").append(e.getMessage());
if (e.getCause() != null) {
sb.append(", 原因: ").append(e.getCause().getMessage());
}
// 添加业务上下文
sb.append(", 时间: ").append(LocalDateTime.now());
sb.append(", 线程: ").append(Thread.currentThread().getName());
return sb.toString();
}
}
最佳实践总结
异常处理原则
public class ExceptionBestPractices {
// ✅ 正确:使用具体的异常类型
public void specificException() {
try {
processStream(inputStream);
} catch (IOException e) {
throw new BusinessException("流处理失败", e);
}
}
// ❌ 错误:捕获过于宽泛的异常
public void broadException() {
try {
processStream(inputStream);
} catch (Exception e) { // 太过宽泛
throw new BusinessException("处理失败", e);
}
}
// ✅ 正确:异常转换时保留原始异常
public void preserveCause() {
try {
databaseOperation();
} catch (SQLException e) {
throw new BusinessException("数据库操作失败", e); // 保留cause
}
}
// ❌ 错误:丢弃原始异常信息
public void loseCause() {
try {
databaseOperation();
} catch (SQLException e) {
throw new BusinessException("数据库操作失败"); // 丢失原始异常
}
}
}
异常处理检查清单
- [x] 是否使用了具体的异常类型?
- [x] 自定义异常是否继承自合适的父类?
- [x] 异常信息是否包含足够的上下文?
- [x] 是否保留了原始异常堆栈?
- [x] 资源是否正确关闭(try-with-resources)?
- [x] 是否避免在finally中抛出异常?
- [x] 异常日志是否包含关键信息?
- [x] 是否实现了统一异常处理?
这样的异常处理架构能够保证代码的健壮性、可维护性和可读性,同时提供了清晰的错误反馈给调用方。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播