Using Singleton in the Constructor

I have a Singleton Logger class.

 public class Logger { public static Logger INSTANCE = new Logger(); private Logger() { ... } } 

I want my constructor to start a new instance. So my code is as follows:

 public class MyClass { public MyClass() { Logger.INSTANCE.log("MyClass created"); ... } } 

I am wondering if this could break static instances of MyClass . For example, if I have:

 public class MyOtherClass { private static MyClass myClass = new MyClass(); ... } 

I am afraid that this might cause a problem due to the undefined order of initialization of static variables. Therefore, if MyClass initialized before Logger.INSTANCE , then the MyClass construction fails. Is there any mechanism to prevent this, or is using static variables in the constructor inherently dangerous? Is there a way to prevent users from creating static instances of MyClass in this case?

+4
source share
4 answers
 public class Logger { public static Logger INSTANCE = new Logger(); private Logger() { ... } } 

Is syntactic sugar for

 public class Logger { public static Logger INSTANCE; static { INSTANCE = new Logger(); } private Logger() { ... } } 

The static block sets the static members of the class, and is guaranteed to run before your class is used .

+4
source

I recommend you wrap your Logger.INSTANCE, as in the classic singleton:

 public class Logger{ private static Logger logger; private Logger(){ } public static Logger getInstance(){ if(logger==null){ logger = new Logger(); } return logger; } } 

That way, when you call Logger.getInstance() , you will never get null .

If you need a thread safe singleton:

 public class Logger { private static class Holder { static final Logger INSTANCE = new Logger(); } public static Logger getInstance() { return Holder.INSTANCE; } } 

That way, you will also never get null , because by default Logger will be initialized before the class where it will be used, because in this case it will be a dependency of another class.

+1
source

So, if myClass is initialized before Logger.INSTANCE, then the construction of myClass will be destroyed.

You cannot initialize a class until all its classes have been initialized.

Is there any mechanism to prevent this, or is using static variables in the constructor inherently dangerous?

You cannot use a class before it has been initialized (unless you call it in the initialization code)

Is there a way to prevent users from creating static instances of MyClass in this case?

You cannot instantiate a class until the classes that it uses have been initialized.

0
source

No need to worry about breaking anything, the JVM will provide the right construction order. However, when accessing my many threads, many instances arise. Improve the code declaring singleton as final, and using the static method to access:

 public class Logger { private static final Logger INSTANCE = new Logger(); private Logger() {} public static Logger getInstance() { return INSTANCE; } } 
0
source

All Articles