单例类中的私有静态变量和私有实例变量有什么区别?

时间:2012-01-12 00:37:24

标签: java singleton

单例类中的私有静态变量和私有实例变量有什么区别?

我认为没有语义差异。

编辑:不询问持有自身实例的变量是否应该是静态的,而是其他数据成员。

5 个答案:

答案 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)

可能最好在单例中实现它,因为这样你可以覆盖单例以进行测试和类似。此外,您将静态保持在一个位置。