Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserializing a singleton in java

I am going through Effective Java, and came across this example.

class Elvis implements Serializable {
    public static final Elvis  inst = new Elvis();
    private Elvis() {
        System.out.println("In elvis constructor ");
    }

    public static Elvis getInstance() {
        return inst;
    }
}

According to the book, when i deserialize, a new ELVIS object should be constructed, but i see the constructor is not called at the time of deserialization?

Here is my code which serializes, and deserializes.

FileOutputStream fos = new FileOutputStream("myserial1.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Elvis e = Elvis.getInstance();
System.out.println(" e = "+e.getInstance());

oos.writeObject(e);

System.out.println("Serialization done.");
FileInputStream fis = new FileInputStream("myserial1.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Elvis el = (Elvis) ois.readObject();
System.out.println(" el = "+el.getInstance());

I See both e and e1 are priting the same reference, and constructor is invoked only once.

Am i misunderstanding the concept here?

Please help.

like image 387
Venkat Teki Avatar asked Jan 26 '14 08:01

Venkat Teki


2 Answers

During serialization no constructor is called, fields initialized by deserialization process or readObject() method (if you add this method into your class). If you want to implement a serializable singleton, you should additionally add readResolve() method as it described here.


PS.
Keep in mind that getInstance() is a static method of class Elvis, so such calls as e.getInstance() and el.getInstance() are equals to Elvis.getInstance().

like image 191
Philip Voronov Avatar answered Sep 29 '22 14:09

Philip Voronov


Am i misunderstanding the concept here?

What you are misunderstanding is that a constructor creates an object. No it doesn't. Constructor just initializes the object. Now, deserialization need not invoke the constructor, as it already has the state of the serialized object, and that is what it has to provide us.

However, if in the hierarchy of serializable class, there is some non-serializable class, then it's constructor would be invoked to initialize the state in that class, as it has not been serialized.

You can go through the Serialization Specification.

like image 30
Rohit Jain Avatar answered Sep 29 '22 13:09

Rohit Jain