Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Singleton via enum way is lazy initialized?

Tags:

java

singleton

This is a very wide-spread enum singleton code:

public enum enumClazz{
   INSTANCE
   enumClazz(){
     //do something
   }
}

and a bunch of places said it is a lazy initialization. But I am confused after I read Chapter 7 of 'Inside the Java Virtual Machine' -- The Lifetime of a Type:

The Java virtual machine specification gives implementations flexibility in the timing of class and interface loading and linking, but strictly defines the timing of initialization. All implementations must initialize each class or interface on its first active use. The following six situations qualify as active uses:

  • A new instance of a class is created (in bytecodes, the execution of a new instruction. Alternatively, via implicit creation, reflection, cloning, or deserialization.)
  • The invocation of a static method declared by a class (in bytecodes, the execution of an invokestatic instruction)
  • The use or assignment of a static field declared by a class or interface, except for static fields that are final and initialized by a compile-time constant expression (in bytecodes, the execution of a getstatic or putstatic instruction)
  • The invocation of certain reflective methods in the Java API, such as methods in class Class or in classes in the java.lang.reflect package
  • The initialization of a subclass of a class (Initialization of a class requires prior initialization of its superclass.)
  • The designation of a class as the initial class (with the main()< method) when a Java virtual machine starts up

The third point with bold style clarify that if the field is static final, the initialization of the field is happened at compile-time. Likewise, the INSTANCE in enumClazz is implicitly equal to public static final and comply with the third point.

Can someone correct me if my understanding is wrong?

like image 921
vash_ace Avatar asked May 27 '13 10:05

vash_ace


People also ask

Is enum singleton lazy?

In your case, the singleton will be initialised when the enum class is loaded, i.e. the first time enumClazz is referenced in your code. So it is effectively lazy, unless of course you have a statement somewhere else in your code that uses the enum.

Does singleton allow lazy initialization?

Lazy initialization is possible. It is also thread safe.

Is enum singleton thread safe?

By default, the Enum instance is thread-safe, and you don't need to worry about double-checked locking. In summary, the Singleton pattern is the best way to create Singleton in Java 5 world, given the Serialization and thread-safety guaranteed and with some line of code enum.

How would you implement singleton using enum?

The singleton pattern restricts the instantiation of a class to one object. INSTANCE is a public static final field that represents the enum instance. We can get the instance of the class with the EnumSingleton. INSTANCE but it is better to encapsulate it in a getter in case if we want to change the implementation.


2 Answers

enum instance fields are not "initialized by a compile-time constant expression". They can't be, because only String and primitive types are possible types for a compile-time constant expression.

That means that the class will be initialized when INSTANCE is first accessed (which is exactly the desired effect).

The exception in the bold text above exists, because those constants (static final fields initialized with a compile-time constant expression) will effectively be inlined during compilation:

class A {
  public static final String FOO = "foo";

  static {
    System.out.println("initializing A");
  }
}

class B {
  public static void main(String[] args) {
    System.out.println(A.FOO);
  }
}

Executing class B in this example will not initialize A (and will not print "initializing A"). And if you look into the bytecode generated for B you'll see a string literal with the value "foo" and no reference to the class A.

like image 195
Joachim Sauer Avatar answered Oct 07 '22 09:10

Joachim Sauer


The third point with bold style clarify that if the field is 'static final', the initialzation of the field is happened at complie-time

Not exactly - it only applies to "static fields that are final and initialized by a compile-time constant expression":

static final String = "abc"; //compile time constant
static final Object = new Object(); //initialised at runtime

In your case, the singleton will be initialised when the enum class is loaded, i.e. the first time enumClazz is referenced in your code.

So it is effectively lazy, unless of course you have a statement somewhere else in your code that uses the enum.

like image 5
assylias Avatar answered Oct 07 '22 11:10

assylias