在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


相关推荐: 网站建设整体流程解析,建站其实很容易!  如何在阿里云高效完成企业建站全流程?  Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南  Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控  ,网页ppt怎么弄成自己的ppt?  如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框  在线制作视频网站免费,都有哪些好的动漫网站?  Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】  Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】  如何做网站制作流程,*游戏网站怎么搭建?  Firefox Developer Edition开发者版本入口  mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?  使用豆包 AI 辅助进行简单网页 HTML 结构设计  如何在云虚拟主机上快速搭建个人网站?  使用spring连接及操作mongodb3.0实例  WEB开发之注册页面验证码倒计时代码的实现  Laravel怎么进行浏览器测试_Laravel Dusk自动化浏览器测试入门  Laravel如何记录自定义日志?(Log频道配置)  如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程  网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?  javascript基于原型链的继承及call和apply函数用法分析  如何用AWS免费套餐快速搭建高效网站?  android nfc常用标签读取总结  如何挑选优质建站一级代理提升网站排名?  如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体  清除minerd进程的简单方法  青岛网站建设如何选择本地服务器?  Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件  logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  Laravel如何使用Passport实现OAuth2?(完整配置步骤)  Laravel如何构建RESTful API_Laravel标准化API接口开发指南  Laravel怎么定时执行任务_Laravel任务调度器Schedule配置与Cron设置【教程】  Laravel如何使用Socialite实现第三方登录?(微信/GitHub示例)  非常酷的网站设计制作软件,酷培ai教育官方网站?  如何在自有机房高效搭建专业网站?  最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?  海南网站制作公司有哪些,海口网是哪家的?  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  Laravel如何创建自定义Artisan命令?(代码示例)  微信小程序 闭包写法详细介绍  linux写shell需要注意的问题(必看)  如何在腾讯云服务器快速搭建个人网站?  ,交易猫的商品怎么发布到网站上去?  Laravel如何使用Eloquent ORM进行数据库操作?(CRUD示例)  详解Android中Activity的四大启动模式实验简述  三星、SK海力士获美批准:可向中国出口芯片制造设备  Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作  Laravel如何与Pusher实现实时通信?(WebSocket示例)  如何在局域网内绑定自建网站域名?  如何获取PHP WAP自助建站系统源码?