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("
Using 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
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…