在Java中如何自定义异常类_Java自定义异常实现解析

发布时间 - 2026-02-03 00:00:00    点击率:
Java自定义异常需根据checked/unchecked需求选择继承Exception或RuntimeException;必须提供4个标准构造函数;建议显式声明serialVersionUID;异常名须以Exception结尾,避免日志泄露敏感信息。

Java 中自定义异常类不是必须继承 Exception,而是取决于你想要的是**检查型异常(checked)**还是**非检查型异常(unchecked)**:继承 Exception(或其子类,但非 RuntimeException)得到 checked 异常;继承 RuntimeException 得到 unchecked 异常。

继承 Exception 还是 RuntimeException

这是最关键的取舍点,直接影响调用方是否被强制处理:

  • Exception 及其子类(除 RuntimeException 外):编译器强制要求 try-catchthrows,适合业务中「预期可能出错且调用方必须决策」的场景,比如 InsufficientBalanceException
  • RuntimeException 及其子类:无需显式处理,适合「程序逻辑错误或不应恢复的异常」,比如 InvalidOrderStatusException(状态非法通常是代码 bug,不是正常业务分支)
  • 别直接继承 Throwable——会绕过 Java 异常分类机制,导致行为不可预测

必须实现的构造函数有哪些?

标准做法是提供以下

4 个构造函数,覆盖所有常见调用方式:

public class PaymentFailedException extends Exception {
    public PaymentFailedException() {
        super();
    }

    public PaymentFailedException(String message) {
        super(message);
    }

    public PaymentFailedException(String message, Throwable cause) {
        super(message, cause);
    }

    public PaymentFailedException(Throwable cause) {
        super(cause);
    }
}

原因:catch 块中抛出新异常时经常需要包装原异常(cause),而日志或框架(如 Spring)在序列化/打印堆栈时依赖这些构造函数。缺任何一个都可能导致 NullPointerException 或丢失原始异常信息。

要不要加 serialVersionUID

要,尤其是异常类可能被序列化(例如在分布式 RPC、RMI 或某些消息队列场景中):

  • 不加 serialVersionUID:JVM 自动生成,但只要类结构稍有改动(比如新增字段),反序列化就会失败,报 InvalidClassException
  • 显式声明:值可固定为 1L 或用 IDE 自动生成,确保兼容性
  • 如果确定该异常**永远不会跨 JVM 传输**(纯本地服务内使用),可省略,但建议统一加上,避免后续扩展踩坑

实际使用中容易忽略的细节

自定义异常真正落地时,最常被跳过的其实是语义清晰和上下文携带:

  • 异常名必须以 Exception 结尾(如 UserNotFoundException),否则违反 Java 约定,IDE 和静态检查工具(如 Sonar)会警告
  • 不要在异常消息里拼接敏感数据(如密码、token),避免日志泄露;可用占位符 + toString() 或专用字段存储 ID、订单号等安全上下文
  • 如果需要传递额外信息(如错误码、HTTP 状态码),建议添加 private final int errorCode; 字段,并提供 getter,而不是靠解析 getMessage()
  • Spring 项目中,若用于 @ControllerAdvice 全局捕获,记得确认异常类没被 AOP 代理拦截(比如被 @Transactional 包裹时,unchecked 异常才触发回滚)


# java  # 工具  #   # ai  # 状态码  # 一加  # 敏感数据  # spring  # 分布式  # jvm  # 子类  # 构造函数  # try  # catch  # Token  # int  # 继承  #   # private  # ide  # http  # rpc  # bug  # 自定义  # 序列化  # 自动生成  # 的是  # 这是  # 就会  # 尤其是  # 不应  # 任何一个 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Java类加载基本过程详细介绍  php485函数参数是什么意思_php485各参数详细说明【介绍】  Laravel如何使用withoutEvents方法临时禁用模型事件  Laravel PHP版本要求一览_Laravel各版本环境要求对照  如何在阿里云虚拟服务器快速搭建网站?  香港服务器建站指南:免备案优势与SEO优化技巧全解析  Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】  在线制作视频的网站有哪些,电脑如何制作视频短片?  如何在服务器上配置二级域名建站?  Laravel如何创建自定义Facades?(详细步骤)  Laravel如何为API生成Swagger或OpenAPI文档  大同网页,大同瑞慈医院官网?  JS去除重复并统计数量的实现方法  Swift开发中switch语句值绑定模式  Laravel如何使用Laravel Vite编译前端_Laravel10以上版本前端静态资源管理【教程】  Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  高端企业智能建站程序:SEO优化与响应式模板定制开发  Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例  Bootstrap整体框架之JavaScript插件架构  打造顶配客厅影院,这份100寸电视推荐名单请查收  Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性  Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】  Laravel辅助函数有哪些_Laravel Helpers常用助手函数大全  php增删改查怎么学_零基础入门php数据库操作必知基础【教程】  Laravel如何使用Blade组件和插槽?(Component代码示例)  在Oracle关闭情况下如何修改spfile的参数  Angular 表单中正确绑定输入值以确保提交与验证正常工作  如何在万网开始建站?分步指南解析  Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程  Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】  HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】  深圳网站制作的公司有哪些,dido官方网站?  如何使用 Go 正则表达式精准提取括号内首个纯字母标识符(忽略数字与嵌套)  如何在腾讯云免费申请建站?  在线制作视频网站免费,都有哪些好的动漫网站?  宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程  html5audio标签播放结束怎么触发事件_onended回调方法【教程】  创业网站制作流程,创业网站可靠吗?  深入理解Android中的xmlns:tools属性  郑州企业网站制作公司,郑州招聘网站有哪些?  PythonWeb开发入门教程_Flask快速构建Web应用  如何在IIS7中新建站点?详细步骤解析  php 三元运算符实例详细介绍  Edge浏览器如何截图和滚动截图_微软Edge网页捕获功能使用教程【技巧】  Laravel Admin后台管理框架推荐_Laravel快速开发后台工具  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  网站制作软件免费下载安装,有哪些免费下载的软件网站?  使用spring连接及操作mongodb3.0实例  Swift中swift中的switch 语句