为什么`readResolve`是一个实例方法,如果它返回调用对象?

时间:2016-06-03 19:27:16

标签: java singleton deserialization

我知道readResolve是处理创建/返回反序列化对象的钩子。它可以在确保Singleton类即使在多次反序列化后只有一个对象的情况下使用。但该方法是实例方法,并在其对象被反序列化的类中定义。那么为什么这个方法首先被调用呢?还有其他功能吗?

2 个答案:

答案 0 :(得分:1)

你误解了。 (De)Serialization从字节创建一个对象,然后询问该对象是否要替换它。

private Object readResolve() {
    return this;
}

是实现此方法的完美方式。它毫无意义,因为它意味着“不能取代我”#34;。当这种方法不存在时,会发生同样的事情。

您可以在反序列化以下

时使其可见
class Elvis implements Serializable {
    { System.out.println("Initializer of " + this); }
    private Elvis() { System.out.println("Constructor of " + this); }

    static final Elvis THE_ELVIS = new Elvis();

    private Object readResolve() {
        System.out.println("readResolve of " + this);
        new Exception("This is how we get called:").printStackTrace();
        return THE_ELVIS; // we're not the real one and don't want to be
                          // the result of deserialization. Replace with
                          // proper instance.
    }
}

http://ideone.com/kd2PdS

答案 1 :(得分:0)

反序列化开始反序列化的对象,然后调用其readResolve()方法(如果存在)以确定readObject()实际返回的内容。它可以像你说的那样用来替换同一个类的单例实例,或者它可以用来返回一个完全不同的类的实例。例如,当相应的writeObjext()方法替换了一个代理对象时被序列化。