Reputation: 532
I have read about better approaches for Singleton implementation.
It was mentioned that,
But I did not understand one thing. If the readResolve method will replace the serialized value, then why we are doing the serialization process? Instead we need not implement serializable interface know?
For Example, I have the following Singleton Class,
package singleton;
import java.io.Serializable;
public class ClassicSingleton implements Serializable {
private static final long serialVersionUID = 1L;
private static ClassicSingleton classicSingleton = new ClassicSingleton();
private int num;
private ClassicSingleton() {
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public static ClassicSingleton getInstance() {
return classicSingleton;
}
protected Object readResolve() {
ClassicSingleton cs = getInstance();
cs.setNum(23);
return cs;
}
}
And this is where, I am doing the serialization,
package singleton;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class SingletonExample {
public static <T> void main(String args[]) throws FileNotFoundException,
IOException, ClassNotFoundException {
ClassicSingleton classicSingleton = ClassicSingleton.getInstance();
classicSingleton.setNum(5);
serialize(classicSingleton);
}
public static <T> void serialize(T t) throws FileNotFoundException,
IOException {
ObjectOutputStream oop = new ObjectOutputStream(new FileOutputStream(
"file1.txt"));
oop.writeObject(t);
oop.close();
}
}
DeSerialization code
package singleton;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
public class SerializeInAnotherFIle {
public static <T> void main(String[] args) throws FileNotFoundException,
ClassNotFoundException, IOException {
T object = deSerialize();
ClassicSingleton classicSingleton= (ClassicSingleton) object;
ClassicSingleton classicSingleton2 = deSerialize();
System.out.println("Is serialized and deserialized are same? :"+(classicSingleton == classicSingleton2));
System.out.println("Classic Singleton :"
+ classicSingleton.getNum());
}
public static <T> T deSerialize() throws FileNotFoundException,
IOException, ClassNotFoundException {
ObjectInputStream oip = new ObjectInputStream(new FileInputStream(
"file1.txt"));
T object = (T) oip.readObject();
oip.close();
return object;
}}
Since, I am defining my readResolve method, My output is always 23. The serialized values are not coming. So my doubt is why Serialization and readResolve together, because both are doing opposite.
Upvotes: 1
Views: 1206
Reputation: 560
Well I found answer to this question at http://codepumpkin.com/serializable-singleton-design-pattern/
Here is the summary from this link :
Why do we need to make our Singleton class Serializable?
Well it is not at all required. There is no useful real world scenario where we require to Serialize Singleton Object. A singleton usually doesn't change of state throughout its lifetime nor contains any state which we can save/restore. If it does, then it is already wrong to make it a singleton.
Java SE API contains two Singleton implementation java.lang.Runtime
and java.awt.Desktop
. None of them implements serializable
. It also doesn't make any sense as well.
However, here is one case where we may require to handle Serialization while implementing Singleton Design Pattern.
What if super class has implemented Serialization interface?
If our Singleton class is required to inherit all the properties of some class i.e. ParentClass and that class is Serializable. For Example,
class ParentClass implements Serializable{
}
public class SerializableSingleton extends ParentClass {
// Singleton Code
}
Well in this case, we need to take all the preventive actions like make all the fields transient and provide readResolve()
method implementation.
There is also one more approach to handle this scenario. Override writeObject() method and throw a NotSerializableException
from it. It will behave same as you have not implemented Serializable
interface.
Upvotes: 1
Reputation: 8161
Reason is Nobody can create another instance of the singleton object by serializing and deserializing the singleton.
readResolve is used for replacing the object read from the stream. you hard-coded it with cs.setNum(23); that is why it always returns 23. If you don't want to do manipulation with the data, Edit your code as below
protected Object readResolve() {
return this;
}
Reason: readResolve is called after readObject has returned. The object the method returns replaces this object returned to the user of ObjectInputStream.readObject.
Upvotes: 0