Java serialization: readObject() vs. readResolve()

前端 未结 10 938
花落未央
花落未央 2020-12-02 04:07

The book Effective Java and other sources provide a pretty good explanation on how and when to use the readObject() method when working with serializable Java class

相关标签:
10条回答
  • 2020-12-02 04:39

    readResolve() will ensure the singleton contract while serialization.
    Please refer

    0 讨论(0)
  • 2020-12-02 04:41

    As already answered, readResolve is an private method used in ObjectInputStream while deserializing an object. This is called just before actual instance is returned. In case of Singleton, here we can force return already existing singleton instance reference instead of deserialized instance reference. Similary we have writeReplace for ObjectOutputStream.

    Example for readResolve:

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    public class SingletonWithSerializable implements Serializable {
    private static final long serialVersionUID = 1L;
    
    public static final SingletonWithSerializable INSTANCE = new SingletonWithSerializable();
    
    private SingletonWithSerializable() {
        if (INSTANCE != null)
            throw new RuntimeException("Singleton instance already exists!");
    }
    
    private Object readResolve() {
        return INSTANCE;
    }
    
    public void leaveTheBuilding() {
        System.out.println("SingletonWithPublicFinalField.leaveTheBuilding() called...");
    }
    
    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
        SingletonWithSerializable instance = SingletonWithSerializable.INSTANCE;
    
        System.out.println("Before serialization: " + instance);
    
        try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("file1.ser"))) {
            out.writeObject(instance);
        }
    
        try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("file1.ser"))) {
            SingletonWithSerializable readObject = (SingletonWithSerializable) in.readObject();
            System.out.println("After deserialization: " + readObject);
        }
    
    }
    

    }

    Output:

    Before serialization: com.ej.item3.SingletonWithSerializable@7852e922
    After deserialization: com.ej.item3.SingletonWithSerializable@7852e922
    
    0 讨论(0)
  • 2020-12-02 04:45

    readResolve is used for replacing the object read from the stream. The only use I've ever seen for this is enforcing singletons; when an object is read, replace it with the singleton instance. This ensures that nobody can create another instance by serializing and deserializing the singleton.

    0 讨论(0)
  • 2020-12-02 04:45

    readResolve can be used to change the data that is serialized through readObject method. For e.g. xstream API uses this feature to initialize some attributes that were not in the XML to be deserialized.

    http://x-stream.github.io/faq.html#Serialization

    0 讨论(0)
提交回复
热议问题