简体   繁体   English

Singleton vs public static final变量

[英]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. 然而,常见的习惯是将实例变量设为私有并通过getter返回它,这样其他代码就不会直接依赖它。 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: 这样,如果将来你决定想要更高级的东西(例如,你提到的延迟初始化),你可以轻松地重构你的代码而不破坏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. 您的第一个代码使用带有synchronized关键字的延迟创建。 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 : instance = new ClassName()这些代码的问题是instance var在构造单例之前可能变为非null,并且可以在伪代码中解释,JRE用于创建实例:

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. 因此,如果多个线程同时访问方法getInstance,是否有可能获得一个新实例,因为在java中你有2条指令和JRE解释的伪代码在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/ 这来自法国文章: 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). 人们说'全局变量是坏的'(我来自C ++世界,所以措辞是C ++特定的,但想法是一样的)。 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. 我个人发现Singleton只有一个好处 - 延迟初始化,这使得控制实例化的顺序成为可能。 If it is not needed, Singleton is not needed. 如果不需要,则不需要Singleton。

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. 优势来自于单例的编写者可以更新getter(getInstance)以获得更复杂的规则,而不会导致单例的用户必须重新编译他们的代码。 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" 这就是Mureinik所说的:“那样,如果将来你决定想要更高级的东西(例如,你提到的延迟初始化),你就可以轻松地重构你的代码而不会破坏API”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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