gpt4 book ai didi

java - 反序列化时跳过新的 transient 字段

转载 作者:行者123 更新时间:2023-12-02 00:51:29 26 4
gpt4 key购买 nike

我继承了以下代码(以及使用它存储的数据,即 A 的序列化实例):

class A implements Serializable {
private static final long serialVersionUID = 1L;
int someField;
B b;
}

class B implements Serializable {
private static final long serialVersionUID = 1L;
int someField;
}

在某些时候,我意识到 A 中的 b 字段实际上不应该被持久化(并且 B 根本不应该被序列化),所以我将其更改为:

class A implements Serializable {
private static final long serialVersionUID = 1L;
int someField;
transient B b;
}

class B {
int someField;
}

如果我创建一个 A 的新实例并序列化它,那么反序列化它就没有问题。但是,如果我尝试反序列化与旧代码一起存储的 A 实例,则会收到以下形式的异常:

java.io.InvalidClassException: B; B; class invalid for deserialization
at java.io.ObjectStreamClass.checkDeserialize(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)

我相信这是因为持久化数据还存储了 AB 的类描述,而这些人仍然认为 b > 仍然存在,即使在当前版本中它们不再存在(请参阅 ObjectStreamClass 中的第 600 到 606 行)

有没有办法强制 A 的反序列化跳过现在是 transient 的字段?例如,是否有一种方法可以覆盖反序列化代码在 ObjectInputStream 中读取的类描述并更新其 b 的定义,以便它知道其 transient ?

最佳答案

在反序列化期间没有跳过某些字段的技巧。事实上,(几乎)对类的源代码所做的任何更改都会使旧的序列化数据无法反序列化。序列化将源代码与序列化数据紧密结合。

这就是序列化不适合长期数据存储的原因。序列化仅适用于 RMI(通过网络传输对象)或磁盘上的临时存储等情况。使用记录良好的(标准)文件格式而不是 Java 序列化来进行长期数据存储。

您可以做的是使用旧代码反序列化数据,然后将其写入另一种格式,然后仅使用该格式。

关于java - 反序列化时跳过新的 transient 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2849798/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com