Prevent the singleton pattern from being broken

Summarized two methods, if there are other methods, welcome to add bloggers
1. The introduction of the reflection mechanism to destroy the singleton pattern
The following is a singleton class, we generate an instance of this class through the reflection mechanism
public class Singleton {
    public static final Singleton INSTANCE = new Singleton();
    private Singleton() {
    }
    public Singleton getInstance() {
        return INSTANCE;
    }
    public static void main(String[] args) throws Exception {
        // Reflection mechanism destroys singleton pattern
        Class clazz = Singleton.class;
  // get the constructor
        Constructor c = clazz.getDeclaredConstructor();
        // Reflection mechanism makes private methods accessible
        c.setAccessible(true);
        // Determine whether the object generated by reflection is equal to the singleton object
        System.out.println(Singleton.INSTANCE == c.newInstance());
    }
}


The constructor of the singleton class is obtained through reflection. Since the constructor is private, setAccessible(true) indicates that the reflected object should cancel the Java language access check when it is used,
so that the private constructor can be accessed, which makes the singleton Mode is invalid.
2. Serialization mechanism to destroy the singleton mode
Serialization
can generate objects from bytecode, so serialization may also destroy the singleton mode An instance of a singleton class
public class Singleton implements Serializable {
    public static final Singleton INSTANCE = new Singleton();
    private Singleton() {
    }
    public static void main(String[] args) throws Exception {
        // Objects that support java.io.Serializable can be written to the stream
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(Singleton.INSTANCE);
        // Generate object from byte stream
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        Singleton newSingleton = (Singleton) ois.readObject();
        System.out.println(newSingleton == Singleton.INSTANCE);
    }
}


Why does the only instance of the singleton pattern have to be static?
Then the crux of the problem comes. There are only two ways for a program to call a method in a class. ①Create an object of the class and use the object to call the method in the class; ②Use the class name to directly call the method in the class, in the format "class name.method name" ()";
As mentioned above, the first case cannot be used after the constructor is privatized, and only the second method can be used.
And use the class name to directly call the method in the class, the method in the class must be static, and the static method cannot access non-static member variables, so the instance variables customized by the class must also be static.
This is why the singleton pattern only instance must be set to static.

Prevent reflections from destroying simple interest mode
 
public class ElvisModified  
{  
    private static boolean flag = false;  
 
    private ElvisModified(){  
        synchronized(ElvisModified.class)  
        {  
            if(flag == false)  
            {  
                flag = !flag;  
            }  
            else
            {  
                throw new RuntimeException("Singleton pattern is violated!");  
            }  
        }  
    }  


Prevent serialization from breaking simple interest mode
private Object readResolve(){
return instance;
}

Generally speaking, if a class implements the Serializable interface, we can write it into memory and read it from memory to "assemble" it into an object that is exactly the same as the original.
When the JVM deserializes and "assembles" an object from memory When a new object is created, the readResolve method will be automatically called to return the object we specified, and the singleton rule is guaranteed.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324607311&siteId=291194637