Java序列化是将对象状态转为字节流以实现持久化或传输的机制,需实现Serializable接口并配合ObjectOutputStream/ObjectInputStream使用;transient和static字段不参与,建议显式声明serialVersionUID以避免版本不兼容;它保存对象状态而非行为,不适合跨语言或长期存储。
Java里的序列化,就是把一个活在内存里的对象“打包成字节流”,让它能存进文件、发到网络另一头,或者等JVM重启后再原样还原回来。它不是魔法,而是一套有明确规则的持久化机制——核心就两条:Serializable 接口标记 + ObjectOutputStream/ObjectInputStream 执行。
Serializable 接口?这不是可选项,而是JVM的硬性准入门槛。没实现这个接口,调用 writeObject() 会立刻

NotSerializableException。它是个纯标记接口(没有方法),作用只有一个:告诉JVM“这个类我允许你深挖它的字段、递归处理引用、生成元数据”。
Serializable,子类实现了也没用——父类字段不会被序列化(除非父类也实现)transient 修饰的字段会被跳过,反序列化后是默认值(null、0、false)static 字段天生不参与序列化——它属于类,不属于某个具体对象serialVersionUID 到底要不要写?要,而且强烈建议显式声明。JVM在没写时会根据类名、字段、方法签名等自动生成一个哈希值;但只要类结构稍有改动(比如加个字段、改个访问修饰符),这个哈希值就变,导致反序列化时抛出 InvalidClassException——哪怕你只是改了个注释。
public class User implements Serializable {
private static final long serialVersionUID = 1L; // 显式声明,稳定可控
private String name;
private int age;
}
1L 就够用,除非你真需要做版本兼容控制(比如旧数据必须能被新类读取)它保存的是对象的**状态**,不是行为。具体包括:
transient、非 static 的字段值(含基本类型和对象引用)serialVersionUID、字段名与类型、继承链信息注意:构造方法、普通方法、final 字段(只要不是 transient)都会被保留值;但不会执行任何构造逻辑——反序列化创建对象时,Serializable 类绕过所有构造器,直接分配内存并填充字段。
最容易被忽略的一点是:序列化不是万能的持久化方案。它耦合JVM版本、类结构、甚至部分JDK实现细节;跨语言、跨平台、长期存储都极不推荐。真正需要持久化的场景(比如用户资料),应该用JSON、Protobuf或数据库——序列化更适合短生命周期的进程内缓存、RMI参数、Session落盘这类“自己人之间快速传一下”的场合。