Below show is the creation on the singleton object.
public class Map_en_US extends mapTree {
private static Map_en_US m_instance;
private Map_en_US
How about this approach for eradicating the static block:
private static Map_en_US s_instance = new Map_en_US() {{init();}};
It does the same thing, but is way neater.
Explanation of this syntax:
The outer set of braces creates an anonymous class.
The inner set of braces is called an "instance block" - it fires during construction.
This syntax is often incorrectly called the "double brace initializer" syntax, usually by those who don't understand what is going on.
Also, note:
m_
is a naming convention prefix for instance (ie member) fields.
s_
is a naming convention prefix for class (ie static) fields.
So I changed the name of the field to s_...
.
// Best way to implement the singleton class in java
package com.vsspl.test1;
class STest {
private static STest ob= null;
private STest(){
System.out.println("private constructor");
}
public static STest create(){
if(ob==null)
ob = new STest();
return ob;
}
public Object clone(){
STest obb = create();
return obb;
}
}
public class SingletonTest {
public static void main(String[] args) {
STest ob1 = STest.create();
STest ob2 = STest.create();
STest ob3 = STest.create();
System.out.println("obj1 " + ob1.hashCode());
System.out.println("obj2 " + ob2.hashCode());
System.out.println("obj3 " + ob3.hashCode());
STest ob4 = (STest) ob3.clone();
STest ob5 = (STest) ob2.clone();
System.out.println("obj4 " + ob4.hashCode());
System.out.println("obj5 " + ob5.hashCode());
}
}
-------------------------------- OUT PUT -------------------------------------
private constructor
obj1 1169863946
obj2 1169863946
obj3 1169863946
obj4 1169863946
obj5 1169863946
Interesting never seen that before. Seems largely a style preference. I suppose one difference is: the static initialisation takes place at VM startup, rather than on first request for an instance, potentially eliminating an issue with concurrent instantiations? (Which can also be handled with synchronized getInstance()
method declaration)
The static block is executed when the class is first loaded by the JVM. As Bruno said, that helps with thread safety because there isn't a possibility that two threads will fight over the same getInstance() call for the first time.
static block is here to allow for init
invocation. Other way to code it could be eg like this (which to prefer is a matter of taste)
public class Map_en_US extends mapTree {
private static
/* thread safe without final,
see VM spec 2nd ed 2.17.15 */
Map_en_US m_instance = createAndInit();
private Map_en_US() {}
public static Map_en_US getInstance(){
return m_instance;
}
@Override
protected void init() {
//some code;
}
private static Map_en_US createAndInit() {
final Map_en_US tmp = new Map_en_US();
tmp.init();
return tmp;
}
}
update corrected per VM spec 2.17.5, details in comments
the static block instances your class and call the default contructor (if any) only one time and when the application starts and all static elements are loaded by the JVM.
Using the getInstance() method the object for the class is builded and initialized when the method is called and not on the static initialization. And is not really safe if you are running the getInstance() in diferent threads at the same time.