不是必须但强烈建议显式声明;因Exception实现Serializable,未声明时JVM自动生成serialVersionUID,类结构变更会导致反序列化失败,如RMI、Dubbo等跨JVM场景。
自定义异常类必须显式声明 serialVersionUID 吗?
不是必须,但强烈建议显式声明。Java 的 Exception 类本身实现了 Serializable,因此所有自定义异常默认可序列化;JVM 会为未声明 serialVersionUID 的类自动生成一个(基于类名、接口、方法签名等计算)。一旦类结构变更(比如新增字段、修改访问修饰符),自动生成的值就会变化,导致反序列化时抛出 InvalidClassException。
什么情况下不写 serialVersionUID 会出问题?
常见于以下场景:
- 异常对象被写入文件或通过网络传给另一 JVM(如 RMI、Dubbo、Spring Cloud Feign fallback 中 throw 的异常)
- 使用了 Java 原生序列化(
ObjectOutputStream/ObjectInputStream)持久化异常实例 - 框架内部捕获并序列化异常后跨节点传递(例如某些消息队列消费者重试时携带原始异常)
此时若服务端升级了异常类(比如加了一个 private String errorCode; 字段),而客户端仍用旧版类反序列化,就会失败。
怎么写才安全?
推荐写法是显式指定一个固定长整型值,并保持长期不变:
立即学习“Java免费学习笔记(深入)”;