readObject()和readResolve()用于恢复瞬态字段

7
根据Serializable javadoc,readResolve()旨在替换从流中读取的对象。但是你肯定不必替换对象,所以将其用于恢复瞬态字段并返回原始引用是否可以,就像这样:
private Object readResolve() {
    transientField = something;
    return this;
}

与使用readObject()相反:
private void readObject(ObjectInputStream s) {
    s.defaultReadObject();
    transientField = something;
}

当仅用于恢复瞬态字段时,选择其中一个是否有任何理由?实际上,我倾向于使用readResolve(),因为它不需要参数,所以在构造对象“正常”时也可以轻松使用,在构造函数中,例如:

class MyObject {

    MyObject() {
        readResolve();
    }

    ...
}
2个回答

4
实际上,readResolve被定义为在反序列化对象时提供更高的控制。因此,您可以自由地做任何您想做的事情(包括设置一个瞬态字段的值)。
然而,我想象您的瞬态字段是设定了一个常量值。否则,这将是某些问题的明显迹象:要么您的字段不是瞬态的,要么您的数据模型依赖于错误的假设。

实际上,该字段不是一个常量值,而是一个 Map,用于从 List(规范表示)中快速查找。没有必要重复存储相同的内容。当然,Map 也可以在第一次需要时进行惰性创建;没有太大区别。 - Joonas Pulakka
好的,其实我主要是在暗示可能存在设计缺陷。不过,你的解释很清楚,在这种情况下readResolve毫无疑问可以解决问题。 - Riduidel

4

使用readResolve方法。readObject方法允许您自定义对象的读取方式,如果格式与预期默认格式不同,则可以使用该方法。但这并非您想做的事情。正如其名称所示,readResolve方法用于在对象被读取后解决对象,并且它的目的恰好是让您解决未在反序列化后还原的对象状态。这就是您要做的事情。您可以从readResolve方法中返回"this"。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接