Java: Lazy Initializing Singleton

前端 未结 5 650
情书的邮戳
情书的邮戳 2020-12-10 16:14

The pattern to create singletons seems to be something like:

public class Singleton {
    private static final Singleton instance = new Singleton();
    priv         


        
5条回答
  •  一整个雨季
    2020-12-10 16:56

    You can use an enum as a Singleton

    enum Singleton {
        INSTANCE;
    }
    

    Say your singleton does something undesirable in unit tests, you can;

    // in the unit test before using the Singleton, or any other global flag.
    System.setProperty("unit.testing", "true");
    
    Singleton.INSTANCE.doSomething();
    
    enum Singleton {
        INSTANCE;
        {
            if(Boolean.getBoolean("unit.testing")) {
               // is unit testing.
            } else {
               // normal operation.
            }
        }
    }
    

    Note: there is no synchronised blocks or explicit lock needed. The INSTANCE will not be loaded until the .class is accessed and not initialised until a member is used. provided you only use Singleton.INSTANCE and not Singleton.class there won't be a problem with the value used to initialise changing later.


    Edit: if you use just the Singleton.class this might not initialise the class. It doesn't in this example on Java 8 update 112.

    public class ClassInitMain {
        public static void main(String[] args) {
            System.out.println("Printing a class reference");
            Class clazz = Singleton.class;
            System.out.println("clazz = " + clazz);
            System.out.println("\nUsing an enum value");
            Singleton instance = Singleton.INSTANCE;
        }
    
        static enum Singleton {
            INSTANCE;
    
            Singleton() {
                System.out.println(getClass() + " initialised");
            }
        }
    }
    

    prints

    Printing a class reference
    clazz = class ClassInitMain$Singleton
    
    Using an enum value
    class ClassInitMain$Singleton initialised
    

提交回复
热议问题