需要有关java中单例类的信息
在提出问题之前,我想先提供代码以便清楚起见。下面是我的单例类代码。
public class CoreData {
private boolean VarA;
private static CoreData instance = null;
protected CoreData() {
// Exists only to defeat instantiation.
}
public static CoreData getInstance() {
if(instance == null) {
instance = new CoreData();
}
return instance;
}
public boolean getVarA(){
return VarA;
}
public void setFirstTime(boolean B){
VarA = B;
}
}
现在我有几个问题要问
- 如果将成员变量 VarA 设为静态会有什么区别?
- 我可以在 getInstance() 方法中初始化成员变量吗?
- 在 Singleton 类中初始化成员变量的最佳实践是什么?
- 把这门课定为最终课有什么意义?
- 将成员变量设为final是什么意思?
我对 java 和 OOPS 很陌生。我现在正在学习。如果有人回答我的问题以提高我的知识,我将不胜感激。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
因为你只有一个实例(或者你认为如此 - 见下文),所以使其静态应该不会产生任何影响。
您的代码不是线程安全的!您可以创建两个实例。原因是,在检查实例是否为空后,另一个线程也可以检查并发现它为空 - 两个线程都会创建实例并返回它们。一个人会“逃脱”。
传统的方法是“双重检查锁定”,其中检查是在同步块内进行的,但正如 Bill Pugh 在他的 著名文章,这是一个损坏的模式。 Java 1.5 引入了 volatile 关键字来解决这个问题,但它仍然是丑陋的代码。
延迟初始化实例的现代最佳实践方法是使用以下模式之一:
或
两者都由语言保证创建单例,但枚举版本是“铁定的” - 可以通过反序列化 hack 来< em>影响静态持有者类模式中实例的状态。除了这个微小的漏洞之外,两者都有效。我更喜欢代码中的第一个选项,因为它避免了类膨胀。
Because you've only got one instance (or so you think - see below) making it static shouldn't make any difference.
Your code is not threadsafe! You could have two instances created. The reason is, after checking instance is null, another thread could also check and find it null - both threads would create instances and return them. One would "escape".
The traditional approach was "double checked locking", where the check is made inside a synchronized block, but as Bill Pugh pointed out in his famous article, that is a broken pattern. Java 1.5 introduced the
volatile
keyword to work around this problem, but it's still ugly code.The modern best practice approach to lazy initialize the instance, is to use one of these patterns:
or
Both are guaranteed by the language to create singletons, but the enum version is "iron-clad " - it is possible through a deserialization hack to affect the instance's state in the static holder class pattern. Apart from that slim vulnerability, both work. I prefer the first option in my code simply because it avoids class bloat.
以后变得非单例会更难
是的。为什么不呢。但实际上构造函数就是为此完成的。
根据最佳实践,您应该使用一些 IoC,并且不要在逻辑代码中放置任何有关范围的代码。
您应该使用
private
构造函数而不是protected
构造函数,或者将其设为final
以防止通过扩展创建多个实例。就像new CoreData(){};
我相信默认情况下所有变量都应该是最终的。它还可以帮助您解决多线程问题。
It will be harder to make it non singleton later
Yeah. Why not. But actually constructors are done for this.
By the best practice you should use some IoC and don't put any code about scope in your logic code.
You should use
private
constructor instead ofprotected
one or make itfinal
to prevent creating several instances by extending. Likenew CoreData(){};
I believe all variables should be final by default. Also it can help you with multi threading issues.