java反序列化需用objectinputstream包装fileinputstream并调用readobject(),对象类须实现serializable接口且建议声明serialversionuid,仅非静态非transient字段被序列化,文件必须为objectoutputstream合法写入的二进制流,推荐try-with-resources管理资源并捕获eofexception处理多对象。

Java 中使用 ObjectInputStream 从文件反序列化对象,核心是:先用 FileInputStream 打开文件,再将其包装为 ObjectInputStream,最后调用 readObject() 方法。但必须注意几个关键前提和细节,否则会抛异常或读取失败。
对象类必须实现 Serializable 接口
被序列化的类(比如 User)必须显式实现 java.io.Serializable 接口,否则运行时会抛 NotSerializableException:
public class User implements Serializable {
private static final long serialVersionUID = 1L; // 建议显式声明
private String name;
private int age;
// 构造器、getter/setter 省略
}
-
serialVersionUID不强制,但强烈建议显式定义,避免因类结构变化导致InvalidClassException - 未被
transient修饰的非静态字段才会被序列化;静态字段和方法不参与序列化
确保文件是合法的序列化数据
该文件必须是由 ObjectOutputStream 正确写入的二进制流,不能是文本、JSON 或其他格式。例如正确写入方式:
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("user.dat"))) {
oos.writeObject(new User("Alice", 28));
}
- 如果文件被手动修改、截断,或用其他方式写入,
readObject()会抛StreamCorruptedException或IOException - 一个文件可连续写入多个对象(多次
writeObject),反序列化时也要对应调用多次readObject()
使用 try-with-resources 安全读取
推荐用 try-with-resources 自动关闭流,避免资源泄漏。反序列化代码示例:
try (FileInputStream fis = new FileInputStream("user.dat");
ObjectInputStream ois = new ObjectInputStream(fis)) {
User user = (User) ois.readObject(); // 注意类型强转
System.out.println(user.getName() + ", " + user.getAge());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
-
readObject()返回Object,需按原类型强转,若类型不匹配会抛ClassCastException -
ClassNotFoundException表示反序列化时找不到该类(如类名变更、未在 classpath 中) - 不要单独关闭
FileInputStream—— 关闭ObjectInputStream即可,它会自动委托关闭底层流
处理多对象或流末尾问题
若文件中存了多个对象,可用循环读取,直到抛出 EOFException(这是正常结束信号):
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("users.dat"))) {
while (true) {
try {
User u = (User) ois.readObject();
System.out.println(u);
} catch (EOFException e) {
break; // 到达文件末尾,正常退出
}
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
- 不要用
ois.available() == 0判断是否结束 —— 对ObjectInputStream无效 - 若不确定文件内容结构,建议在序列化时额外写入对象数量头,或改用更健壮的序列化方案(如 JSON + Jackson)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











