简体   繁体   中英

Singleton vs public static final variable

So I know that the singleton pattern is implemented like this:

public class ClassName {
    private static ClassName instance;

    public static ClassName getInstance() {
        if (instance == null) {
            instance = new ClassName();
        }
        return instance;
    }

    private ClassName() {}
}

What I want to ask is why you couldn't just do it like this:

public class ClassName {
    public static final ClassName instance = new ClassName();
    private ClassName() {}
}

Way fewer lines of code and seems to do exactly the same thing. Minus the lazy initialization of course, but I don't see why lazy initialization would be a significant benefit anyway. I'm not very experienced and would appreciate if you would enlighten me with your knowledge, thanks.

Initializing the singleton instance inline and letting the classloader worry about synchronization may not be an extremely common practice, but it's definitely not unheard of.

The common idiom, however, is to have the instance variable private and return it through a getter so that no other code depends on it directly. That way, if in the future you decide you want something fancier (like, eg, lazy initialization you mentioned), you can easily refactor your code without breaking the API:

public class ClassName {
    private static final ClassName instance = new ClassName();

    public static ClassName getInstance() {
        return instance;
    }

    private ClassName() {}
}

Your first code use lazy creation with the synchronized keyword. instance = new ClassName() the problem with these kind of code is that the instance var could became non-null before the construction of the singleton and can be interpret in pseudo-code, that the JRE do for create the instance :

mem = allocate() ;
instance = mem ;
ctorSingleton(instance)

So if multiple threads access the method getInstance in same time, is it possible you get a new instance, because in java you have 2 instructions and the pseudo-code that the JRE interpret do it in 3.

I consider your second implement is the good one, because you are the sure it will work fine, and Thread or synchronisation problem are hard to fix.

This come from french article : http://christophej.developpez.com/tutoriel/java/singleton/multithread/

This is the same question I always ask singleton-lovers, and in so far, I have not heard a satisfactory answer. People say 'global variables are bad' (I am from C++ world, so wording is C++-specific, but the idea is the same). When I ask how exactly their all-loved Singleton differs from global, I hear only muffed hms. I personally find there is only one benefit to Singleton - lazy initialization, which makes it possible to control the order of instantiation. If it is not needed, Singleton is not needed.

The advantage comes from the fact that the writer of the singleton can update the getter (getInstance) to have more complex rules without causing the users of the singleton to have to recompile their code. This is what Mureinik says: "That way, if in the future you decide you want something fancier (like, eg, lazy initialization you mentioned), you can easily refactor your code without breaking the API"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM