Consider I have a Singleton class defined as follows.
public class MySingleton implements Serializable{ private static MySingleton myInstance; private MySingleton(){ } static{ myInstance =new MySingleton(); } public static MySingleton getInstance(){ return MySingleton.myInstance; } }
The above definition according to me satisfies the requirements of a Singleton.The only additional behaviour added is that the class implements serializable interface.
If another class X get the instance of the single and writes it to a file and at a later point deserializes it to obtain another instance we would have two instances which is against the Singleton principle.
How can I avoid this or am I wrong in above definition itself.
Prevent Singleton Pattern From Deserialization To overcome this issue, we need to override readResolve() method in the Singleton class and return the same Singleton instance.
Serialization:- Serialization can also cause breakage of singleton property of singleton classes. Serialization is used to convert an object of byte stream and save in a file or send over a network.
Thread Safe Singleton in JavaCreate the private constructor to avoid any new object creation with new operator. Declare a private static instance of the same class. Provide a public static method that will return the singleton class instance variable.
I would argue the most common way to implement a singleton is to use an enum with one instance. That might be a "better" way but definitely not the most common way. In all the projects I have worked on, Singletons are implemented as I have shown above.
The best way to do this is to use the enum singleton pattern:
public enum MySingleton { INSTANCE; }
This guarantees the singleton-ness of the object and provides serializability for you in such a way that you always get the same instance.
More generally, you can provide a readResolve()
method like so:
protected Object readResolve() { return myInstance; }
@ColinD is kind of right, but his answer also illustrates why singletons don't really jell with serialization.
Here's what happens when you serialize an enum value (see here).
The rules for serializing an enum instance differ from those for serializing an "ordinary" serializable object: the serialized form of an enum instance consists only of its enum constant name, along with information identifying its base enum type. Deserialization behavior differs as well--the class information is used to find the appropriate enum class, and the Enum.valueOf method is called with that class and the received constant name in order to obtain the enum constant to return.
So any additional state that you attach to your enum values does not survive serialization and deserialization.
You could do the same thing yourself, by adding custom serialization / deserialization code to your singleton classes. That code would need to either not record the singleton's state at all, or throw it away when the singleton is deserialized. Either way, you'd put the logic into a readResolve()
method as explained by @ColinD's answer.
Now, I presume that the reason you want to serialize singletons is that you want to persist their state. Unfortunately, that presents a conceptual problem. Suppose that your application has instantiated the singleton in the normal course of events, and then it deserializes some object graph that includes a copy of a previous instance of the singleton. What can it do?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With