单例类中的私有静态变量和私有实例变量有什么区别?
我认为没有语义差异。
编辑:不询问持有自身实例的变量是否应该是静态的,而是其他数据成员。
答案 0 :(得分:1)
我看到它的方式,如果您假设使用对单个实例的static
引用来实现单例,则只有“没有语义差异”。问题是,static
只是实现单例的一种方式 - 它是一个实现细节。 You can implement singletons other ways, too.
答案 1 :(得分:1)
确实没有区别(除了已经提到的初始化块)。但另一方面,你并没有真正获得任何东西。您仍然需要考虑线程安全性,并且仍然需要确保一次只有一个单例实例。唯一的区别是,如果您想通过公共静态方法发布该成员。但是你为什么要这样做 - 我不知道。
对我个人而言,它也会有点“代码味道”。我的意思是有人做了一个单身人士,仍然宣称其成员是静态的?它告诉我什么?有什么我不知道的吗?或者可能是实现有问题,它必须是静态的(但为什么?!)。但我有点偏执。从我也知道的,没有性能原因,为什么这是一个很好的选择。
答案 2 :(得分:1)
我不确定你在找什么,所以我会写点什么,看看你有什么要说的。
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private double weight; // in pounds
private Elvis() { weight = 300.; } // inaccessible
public static Elvis getInstance() { return INSTANCE; }
public double getWeight() { return weight; }
public void setWeight(double weight) { this.weight = weight; }
}
由于只有一个猫王,你可以使weight
成为静态变量(使用静态getter和setter)。如果你将所有变量都设置为静态,那么定义单例INSTANCE是没有意义的,因为你只有一个只有静态变量和方法的类:
public class Elvis {
private static double weight; // in pounds
static { weight = 300.; } // Could just have set the weight directly above,
// but a static block might be useful for more complex examples.
public static double getWeight() { return weight; }
public static void setWeight(double weight) { this.weight = weight; }
}
我想这应该避免,因为它看起来更像是C中的头文件而不是OO。
有些人可能已经认识到来自J. Bloch“有效Java”的Elvis参考文献。该书中的建议是使用包含一个成员的枚举来实现单例模式:
public enum Elvis {
INSTANCE;
private double weight = 300.;
public double getWeight() { return weight; }
public void setWeight(double weight) { this.weight = weigth; }
}
请注意,由于您通常期望枚举实例是不可变的,因此在这里看起来有点不合标准。
答案 3 :(得分:0)
但是存在差异。 例如,您不能使用静态块来初始化前者。
答案 4 :(得分:-1)
可能最好在单例中实现它,因为这样你可以覆盖单例以进行测试和类似。此外,您将静态保持在一个位置。