gpt4 book ai didi

java - 单例类设计——空对象

转载 作者:搜寻专家 更新时间:2023-10-31 19:31:11 25 4
gpt4 key购买 nike

我和一位同事正在辩论:

我们有一个在我们代码库的多个地方使用的单例类。

最初,类的设计方式是您可以获得类对象,但该对象不会被完全初始化。

我的意思是:

mySingleton.getInstance().SomeMethod();

SomeMethod 会导致错误,因为该类未初始化。为了使类(class)正常工作,必须这样做:

mySingleton.getInstance().initObject();

mySingleton.getInstance().SomeMethod();

无论如何,我的争论是构造函数(用第一个 get 实例调用)应该调用 initObject 以便不会抛出任何错误。

你怎么看?

我的同事喜欢另一种方式,所以他知道类何时初始化。 (即他在 1 个特定的代码行调用 initObject 并希望没有其他东西首先需要它)。

最佳答案

与您的同事相比,您更接近用 Java 实现单例模式的通常方式。请看一下 Wikipedia .在那里您会找到 3 种最常见的 Java 实现:

传统简单方式

public class Singleton {
private static final Singleton INSTANCE = new Singleton();

// Private constructor prevents instantiation from other classes
private Singleton() {}

public static Singleton getInstance() {
return INSTANCE;
}
}

“Bill Pugh 的解决方案”

public class Singleton {
// Private constructor prevents instantiation from other classes
private Singleton() {}

/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder {
public static final Singleton INSTANCE = new Singleton();
}

public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}

使用同步的传统简单方式

public class Singleton {
// volatile is needed so that multiple threads can reconcile the instance
// semantics for volatile changed in Java 5.
private volatile static Singleton singleton;

private Singleton() {}

// synchronized keyword has been removed from here
public static Singleton getSingleton() {
// needed because once there is singleton available no need to acquire
// monitor again & again as it is costly
if (singleton == null) {
synchronized (Singleton.class) {
// this is needed if two threads are waiting at the monitor at the
// time when singleton was getting instantiated
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}

它们都没有使用单独的 initObject() 方法(初始化应该在私有(private)构造函数中进行)。另请注意,如果您有一个单独的公共(public) initObject() 方法,您可能会遇到多线程问题...

顺便说一句,我个人更愿意使用“Bill Pugh”替代方案,但这 3 种方式都是有效的。

编辑 在 Esko 评论之后,我添加了以下实现,维基百科上没有它。我只想补充一点 1) 单例实例不像上面的 3 个选项那样延迟创建; 2) 因为它是一个枚举,所以你不能扩展任何类; 3)这非常非常奇怪。但它在 Java 社区似乎被大肆宣传,所以在这里:

枚举方式

public enum Singleton {
INSTANCE;
Singleton() {
/* Your init code goes here */
}
}

关于java - 单例类设计——空对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4110252/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com