java的序列化以及serialVersionUID 的作用是什么? 📅 2026/7/23 16:55:25 怎么让一个 Java 对象变得可序列化要让一个Java对象可序列化非常简单只需要满足以下几个条件1. 实现java.io.Serializable接口这是一个标记接口Marker Interface里面没有任何方法需要实现。它的作用只是告诉JVM这个类的对象是可以被序列化的。2. 核心注意事项成员变量也必须是可序列化的如果User类中包含另一个自定义类Address的引用那么Address类也必须实现Serializable接口否则在序列化时会抛出NotSerializableException。transient关键字如果某些敏感字段如密码或不需要保存的字段如临时计算结果不需要参与序列化可以使用transient关键字修饰。静态变量static不会被序列化因为静态变量属于类而不属于具体的对象实例。父类的序列化如果一个子类实现了Serializable而父类没有子类仍然可以序列化但反序列化时父类的无参构造函数会被调用以初始化父类的属性。因此父类必须有一个无参构造函数2.serialVersionUID 的作用是什么serialVersionUID 是 Java 序列化机制中的一个版本控制号。它是一个 private static final long 类型的常量。它的核心作用是确保序列化和反序列化过程中类结构的一致性兼容性。在反序列化时JVM 会把传进来的字节流中的 serialVersionUID 与本地相应实体类的 serialVersionUID 进行对比• 如果相同说明两者的版本一致可以成功进行反序列化。• 如果不同JVM 就会抛出 InvalidClassException 异常拒绝反序列化。应用场景当你把一个对象序列化保存到了硬盘上过了一段时间你修改了该类的代码比如增加了一个新字段。• 如果你定义了固定的 serialVersionUIDJava 会尽最大努力帮你兼容新字段会赋予默认值旧字段正常恢复。• 如果你没有定义或者改变了 serialVersionUIDJava 就会认为这是两个完全不同的类直接报错。3.如果不显式定义serialVersionUID会发生什么如果你在类中没有显式声明serialVersionUIDJava 运行时环境JVM会自动根据这个类的结构类名、实现的接口、属性、方法等计算出一个哈希值作为默认的serialVersionUID。这会带来以下严重的问题和隐患1. 极其容易导致InvalidClassException崩溃只要你的类发生了一丁点修改哪怕只是加了一个空格、修改了一个不相干的方法、或者改了一个属性的修饰符编译器重新编译后计算出的默认serialVersionUID就会发生改变。后果之前序列化保存到磁盘上的数据在类修改后将永远无法被反序列化回来。2. 平台和编译器移植性差最致命的问题不同厂商的 JVM如 Oracle HotSpot、IBM J9、OpenJDK或者不同的编译器其计算serialVersionUID的算法可能会有细微差别。后果你在 A 机器Windows 平台使用 Oracle JDK上序列化的对象拿到 B 机器Linux 平台使用 OpenJDK上反序列化时即使类的源码完全一模一样也可能会因为计算出的默认serialVersionUID不同而导致反序列化失败。想·4.最佳实践如果你做的是兼容性修改如新增一个字段不要修改serialVersionUID。如果你做的是非兼容性修改如修改了字段类型或者删除了核心字段需要手动修改serialVersionUID以防止旧数据反序列化时出现逻辑错误。