五分钟精通RuntimeException

Java异常体系

编程讲究强壮性

即确保代码在错误发生时

能按预案妥善处理

Throwable是所有异常的父级

分为两大类:Error和Exception

Error表示系统级错误

通常由JVM抛出

无法由程序处理

而Exception表示程序可处理的异常

需要程序员编码进行处理

RuntimeException

Java里异常分为受检异常和非受检异常

受检异常包括 IOException、ClassNotFoundException

这类异常可以预判到

基本上源自外部因素和环境问题

比如文件有可能读不到

类包没有引入等等

简单判断是不是受检异常

你看到IDE提示需要 try-catch 或 throws 那就是了


复杂的是RuntimeException

顾名思义

只有在运行时才能遭遇

表示程序本身有bug

例如最常见的 NullPointException

对象引用为空 或是没有初始化


到底用哪种异常是初学者最头疼的问题

简而言之

Exception 可以进行 重试、降级、中断等操作

而 Runtime 则应修复代码逻辑

举个例子

操作系统环境、网络等问题配置错误导致的

就用Exception

而Runtime都是与正在运行的代码逻辑相关的

典型Runtime

我们编写代码时会内置很多逻辑规则

当业务规则被违反时

应使用RuntimeException

典型Runtime场景如下:

复制代码
当用户输入不符合预期时,例如长度、类型不正确

当出现数据库操作逻辑错误时,例如SQL写错无法执行

当出现业务逻辑错误时

当系统内部状态不一致时

当出现无法通过外部干预解决的问题时

当需要立即终止当前操作并修复代码时

当出现系统内部bug时

当出现设计缺陷时

当需要立即修复代码而不是处理异常时

Java内置了很多Runtime的子类

根据典型场景可以选择使用

例如

复制代码
当对象未初始化时,应使用子类 NullPointerException

当出现算术错误时,例如除0,应使用子类 ArithmeticException

当出现数组索引越界时,应使用子类 IndexOutOfBoundsException

当出现类型转换错误时,应使用子类 ClassCastException

当出现并发修改异常时,应使用子类 ConcurrentModificationException

当出现数据存储不一致时,应使用子类 ArrayStoreException

当出现空指针时,应使用子类 NullPointerException

当出现参数错误时,应使用子类 IllegalArgumentException

典型Exception

对比Exception

大都是源自于外界因素

通过修改外部环境或者配置都能解决

正常情况下不应出现Exception

典型场景有:

复制代码
当需要返回错误码给前端时

当需要处理网络超时时

当需要处理数据库事务回滚时

以及常用的子类包括:

复制代码
当数据库连接失败时,应使用子类 SQLException

当文件系统操作失败时,应使用子类 IOException

当网络通信失败时,应使用子类 OException

当配置文件不存在时,应使用子类 FileNotFoundException

使用场景归纳

请不要在代码里人工补货 Runtime

例如 Controller、Service、Dao

出现 Runtime 就让他返回更高层

这样可以将异常信息反馈到 View

告诉用户,他违反了什么规则

例如:余额不足、输入为负数、手机号不是11位、没有权限等

特别在Spring项目中

采用 Runtime 就无须层层 throw

可以通过 @ControllerAdvice

在 Controller 返回给前端时

记录日志,并返回友好的错误信息给前端

同时转换为 401、500 等标准 HTTP 状态码

例如:

复制代码
/**
 * 自定义异常类
 */
public class BusinessException extends RuntimeException {
    private final String code;
    private final String traceId;

    public BusinessException(String code, String message) {
        super(message);
        this.code = code;
        this.traceId = java.util.UUID.randomUUID().toString().replace("-", "");
    }
}


@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 处理自定义业务异常
     * HTTP 400 (Bad Request)
     */
    @ExceptionHandler(value = BusinessException.class)
    public ResponseEntity<ApiResponse<Void>> handleBusinessException(BusinessException e) {
        log.warn("业务异常: code={}, message={}, traceId={}", e.getCode(), e.getMessage(), e.getTraceId());
        ApiResponse<Void> response = ApiResponse.fail(e.getCode(), e.getMessage());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
    }

    /**
     * 处理所有未预期的系统异常 (如: NullPointerException, RuntimeException)
     * 对前端返回通用的"系统繁忙"信息,避免暴露敏感信息
     * 记录详细错误日志用于排查
     * 返回 HTTP 500
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ApiResponse<Void>> handleUnexpectedException(Exception e) {
        String traceId = java.util.UUID.randomUUID().toString().replace("-", "");
        log.error("系统内部异常 [TraceID={}]: {}", traceId, e.getMessage(), e);

        ApiResponse<Void> response = ApiResponse.fail("SYSTEM_ERROR", "系统繁忙,请稍后重试");
        response.setTraceId(traceId);

        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
    }
}

这样就能够清晰地传递错误信息

便于调试和处理

确保系统的健壮、可维护

相关推荐
大阿明3 小时前
Spring Boot(快速上手)
java·spring boot·后端
bearpping3 小时前
Java进阶,时间与日期,包装类,正则表达式
java
邵奈一3 小时前
清明纪念·时光信笺——项目运行指南
java·实战·项目
sunwenjian8863 小时前
Java进阶——IO 流
java·开发语言·python
sinat_255487814 小时前
读者、作家 Java集合学习笔记
java·笔记·学习
皮皮林5514 小时前
如何画出一张优秀的架构图?(老鸟必备)
java
百锦再4 小时前
Java 并发编程进阶,从线程池、锁、AQS 到并发容器与性能调优全解析
java·开发语言·jvm·spring·kafka·tomcat·maven
森林猿4 小时前
java-modbus-读取-modbus4j
java·网络·python
tobias.b4 小时前
计算机基础知识-数据结构
java·数据结构·考研
reembarkation4 小时前
光标在a-select,鼠标已经移出,下拉框跟随页面滚动
java·数据库·sql