使用ObjectInputStream反序列化时IIB不执行,如何重建transient私有字段?
Java反序列化时重建private transient字段的解决方案
Java序列化机制预留了自定义反序列化逻辑的扩展入口,你可以通过在实现了Serializable的类中定义特定签名的私有方法,在反序列化阶段手动初始化transient字段。
具体修改方法
在你的StackOverflow类中添加如下readObject方法即可:
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { // 先执行默认反序列化逻辑,处理所有非transient字段 ois.defaultReadObject(); // 手动初始化transient字段 this.stackOverflow = new Object(); }
这个方法是序列化机制约定的回调方法,必须符合私有、返回值为void、入参为ObjectInputStream的签名要求,反序列化时会被自动调用,你可以在内部直接访问类的私有属性完成赋值,不需要对外暴露字段的修改权限。
反序列化构造对象时不会执行类的构造方法、也不会触发实例初始化块,因此transient字段只会被赋予对应类型的默认值(引用类型为null),必须通过上述自定义逻辑手动初始化。
完整修改后代码
import java.io.*; public class StackOverflow implements Serializable { private transient Object stackOverflow; { stackOverflow = new Object(); } // 新增自定义反序列化方法 private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { ois.defaultReadObject(); stackOverflow = new Object(); } public static void main(String[] args) throws IOException, ClassNotFoundException { File object = new File("/Users/user/Desktop/stackoverflow.txt"); try (FileOutputStream fos = new FileOutputStream(object); ObjectOutputStream oos = new ObjectOutputStream(fos)) { oos.writeObject(new StackOverflow()); } try (FileInputStream fis = new FileInputStream(object); ObjectInputStream ois = new ObjectInputStream(fis)) { StackOverflow stackOverflow = (StackOverflow) ois.readObject(); System.out.println(stackOverflow.stackOverflow); // 此时输出不会为null } } }
内容的提问来源于stack exchange,提问作者Solonl
相关产品推荐
相关产品推荐

