366 words
2 minutes
反序列化与序列化

反序列化与序列化基础#

先写一个Person类

public class Person implements java.io.Serializable{
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}

再写一个SerializationTest

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class SerializationTest {
public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}
public static void main(String[] args) throws Exception {
Person person = new Person("aa", 22);
System.out.println(person);
// SerializationTest.serialize(person);
}
}

这是一个非常硬核且关键的 Java 机制问题!

简单的回答是:这是 Java 序列化规范的强制规定。JVM 在反序列化时,只认 private 签名的 readObject 方法。如果是 public,它就不认了,直接忽略你的代码。

让我们深入到底层,看看为什么会这样:

1. “魔法方法”的严格签名#

在 Java 的 Serializable 接口定义中,readObject 被设计为一个回调方法(Callback)

ObjectInputStream 试图反序列化一个对象时,它会通过**反射(Reflection)**机制去检查这个类有没有定义一个“特殊”的方法来处理反序列化逻辑。

Java 官方文档和源码对这个“特殊”方法的签名要求极其严格,必须一字不差

Java

private void readObject(java.io.ObjectInputStream stream)
throws IOException, ClassNotFoundException;

注意那个 private

2. 为什么 public 不行?#

当你把它改成 public void readObject(...) 时:

  1. 反射查找失败(或被跳过): ObjectInputStream 在内部逻辑中(具体是在 ObjectStreamClass
反序列化与序列化
https://origin618.github.io/posts/反序列化与序列化/
Author
Origin
Published at
2025-10-05
License
CC BY-NC-SA 4.0