Article 3 of "Effective Java" uses private constructors or enumeration types to strengthen Singleton properties

Singleton is actually a singleton, that is, a class is only instantiated once in an application and has only one object.

This section discusses three implementation methods

  • Private structure + public members
  • Private constructor + static factory method + private members
  • Enumeration implementation

1. Total members

The constructor is private and has a public immutable instance field of the class type.

1.1 code

public class Singleton01 {
    
    
    public static final Singleton01 singleton01 = new Singleton01();
    private Singleton01(){
    
    }
}

Static fields are created when the class is loaded, and the constructor is private, so a unique instance is guaranteed.

Client call:

Singleton01 singleton01 = Singleton01.singleton01;

1.2 Analysis

  • Advantages: Simple implementation; it can clearly guide that this is a singleton object, because the public static field is final and only one will exist.

  • Disadvantage: You can use reflection to call the private constructor to create the object twice.

2. Static factory method

Define the member as private, provide a static method, and return the object. Also the constructor method is private

2.1 code

public class Singleton02 {
    
    
    /**
     * 私有
     */
    private static final Singleton02 instance = new Singleton02();
    private Singleton02(){
    
    }

    /**
     * 获取唯一的Singleton02实例
     * @return
     */
    public static Singleton02 getInstance(){
    
    
        return instance;
    }
}

For calls to the static method getInstance, the same Singleton02 instance is returned.

Client call:

Singleton02 instance = Singleton02.instance;

2.2 Analysis

  • Advantages: (1) Flexible, you only need to change getInstancethe method to modify whether it is a singleton (for example, create one for each thread); (2) You can use method references to provide parameters, which is elegant to write; (3) You can write paradigms Singleton factory, 30 items are being analyzed.

  • Disadvantages: Compared with 1, it is not obviously a singleton; it does not solve the problem of reflection destroying singletons.

Notice:

In the above two methods, except that reflection calls the private constructor to destroy the singleton, deserialization will also destroy the singleton. To solve the problem of deserialization, you can declare that the instance field is transient and provide one. This is in Article readResolves89 discuss.

private static final transient Singleton02 instance = new Singleton02();

3. Use enumerations

Define the class you want to be a singleton as an enumeration type

3.1 code

public enum Singleton03 {
    
    
    INSTANCE("zhangsan","male");

    private String name;
    private String gender;

    Singleton03(String name, String gender) {
    
    
        this.name = name;
        this.gender = gender;
    }
}

Client use:

Singleton03 instance = Singleton03.INSTANCE;

3.2 Analysis

  • Advantages: Safe, the internal implementation of the enumeration disables reflection and deserialization mechanisms.

  • Disadvantages: If the singleton class must extend a superclass, this does not apply. Because enumerations cannot inherit from other classes.

Guess you like

Origin blog.csdn.net/baidu_40120883/article/details/131870931