Reputation: 61009
I'm following this tutorial for create Singleton and the owner have comment when the method below http://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples
public class EagerInitializedSingleton {
private static final EagerInitializedSingleton instance = new EagerInitializedSingleton();
//private constructor to avoid client applications to use constructor
private EagerInitializedSingleton(){}
public static EagerInitializedSingleton getInstance(){
return instance;
}
}
If your singleton class is not using a lot of resources, this is the approach to use. But in most of the scenarios, Singleton classes are created for resources such as File System, Database connections etc and we should avoid the instantiation until unless client calls the getInstance method.
The Problem Is:
They say we should avoid the instantiation until unless client calls the getInstance method
BUT as I know in this code the instantiation (of object instance) always happened when class EagerInitializedSingleton
load, and EagerInitializedSingleton
just only load when we call EagerInitializedSingleton.getInstance()
=> The instantiation will happened on time with getInstance()
and never before getInstance()
Reference:
Static variables are initialized only once , at the start of the execution(when the Classloader load the class for the first time) . (from https://stackoverflow.com/a/8704607/5381331)
So when are classes loaded?
There are exactly two cases:
- when the new bytecode is executed (for example, FooClass f = new FooClass();)
- and when the bytecodes make a static reference to a class (for example, System.out)
(from http://www.javaworld.com/article/2077260/learn-java/learn-java-the-basics-of-java-class-loaders.html)
Am I wrong or correct. Please give me some sugestion.
Upvotes: 1
Views: 368
Reputation: 6414
They say we should avoid the instantiation until unless client calls the getInstance method
The solution is lazy loading. From wikipedia, Initialization-on-demand holder idiom
When the class Something is loaded by the JVM, the class goes through initialization. Since the class does not have any static variables to initialize, the initialization completes trivially. The static class definition LazyHolder within it is not initialized until the JVM determines that LazyHolder must be executed. The static class LazyHolder is only executed when the static method getInstance is invoked on the class Something, and the first time this happens the JVM will load and initialize the LazyHolder class.
public class Something {
private Something() {}
private static class LazyHolder {
private static final Something INSTANCE = new Something();
}
public static Something getInstance() {
return LazyHolder.INSTANCE;
}
}
Upvotes: 1
Reputation: 5591
I think the problem is when a class gets loaded without the need to get the instance, but for some other reason. You assume that class will be used the first time when user will want to get an instance of that singleton, but it may happen for some other reason, he may just call a class loader for something, or use some 3rd party software to validate a class, anything that comes to mind that involves loading a class but not getting an instance of a singleton.
Upvotes: 1
Reputation: 48434
In this case with that specific code, you are probably correct.
However, if you had static
methods of EagerInitializedSingleton
, or static
non-final
members of EagerInitializedSingleton
referenced somewhere in your code base prior to the invocation of getInstance
, the instance
variable of EagerInitializedSingleton
would initialize.
Same with a reflective invocation of Class.forName
on your EagerInitializedSingleton
class.
Note (and forgive the obvious here) that there are alternative ways of declaring a singleton, including lazy-initialization or enums.
Upvotes: 2