Java serialization: readObject() vs. readResolve()

前端 未结 10 974
花落未央
花落未央 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: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
    

提交回复
热议问题