Removing singleton deserialization in java

I am browsing Effective Java and stumbled upon 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 must be created, but I see that the constructor is not called during deserialization?

Here is my code that 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 assign the same reference, and the constructor is called only once.

I do not understand the concept here?

Please, help.

+6
source share
4 answers

When serializing, the constructor is not called, the fields are initialized by the deserialization process or by the readObject() method (if you add this method to your class). If you want to implement a serializable singleton, you must additionally add the readResolve() method, as described here .


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

+6
source

I do not understand the concept here?

What you misunderstand is that the constructor creates an object. No no. The constructor simply initializes the object. Now deserialization should not call the constructor, since it already has the state of a serialized object, and this is what it should provide to us.

However, if there is some non-serializable class in the hierarchy of a serializable class, then it will be called to initialize the state in this class, since it has not been serialized.

You can follow the Serialization Specification.

+1
source
 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? 

First of all, Object creation and constructor invocation are two separate thing . In a normal scenario, when creating an object with new , the Object keyword is first created, and then the constructor is called. You can see the bytecodes of any java class in which the object is created.

Now, as for your question, in Serialization an object is created like any other object, and instead of running the constructor value / state is restored using reflection . Thus, basically the values ​​are read from the stream (persistent storage is your case) and entered into the object using reflection.

0
source

Since the read and write operation is performed in the same jvm instance and the class has already been loaded for the read operation, and static fields are the atclass storage level. Therefore, here the static variable inst is never required to recreate the public static final Elvis inst = new Elvis();

A link is also a return that was attached with a class level.

0
source

All Articles