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

Java 单例类中私有静态变量和私有实例变量之间的区别是什么?,java,singleton,Java,Singleton,单例类中私有静态变量和私有实例变量之间的区别是什么 我看不出语义上的区别 编辑:不询问保存自身实例的变量是否应为静态变量,而是询问其他数据成员 在我看来,如果您假设singleton是使用对单个实例的static引用实现的,那么只有“没有语义差异”。问题是,static只是实现单例的一种方法——这是一个实现细节 尽管如此,还是有区别的。 例如,您不能使用静态块来初始化前者。可能最好在单例中实现它,因为这样您可以覆盖单例进行测试和类似操作。另外,您将静态状态保持在一个位置。实际上没有区别(除了前面

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

我看不出语义上的区别


编辑:不询问保存自身实例的变量是否应为静态变量,而是询问其他数据成员

在我看来,如果您假设singleton是使用对单个实例的
static
引用实现的,那么只有“没有语义差异”。问题是,
static
只是实现单例的一种方法——这是一个实现细节

尽管如此,还是有区别的。
例如,您不能使用静态块来初始化前者。

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

实际上没有区别(除了前面提到的初始化块)。但另一方面,你也没有真正获得任何东西。您仍然需要考虑线程安全,并且仍然需要确保一次只有一个singleton实例。唯一的区别是,如果希望通过公共静态方法发布该成员。但你到底为什么要这么做——我不知道


对我个人来说,这也有点“代码味道”。我的意思是,有人创建了一个singleton,但仍然将其成员声明为static?它告诉我什么?有什么我不知道的吗?或者可能实现有问题,必须是静态的(但为什么?!)。但我有点偏执。据我所知,这是一个不错的选择,没有性能方面的原因。

我不确定您在寻找什么,所以我将写一些东西,看看您有什么要说的

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; }
}
因为只有一个Elvis,所以可以将
weight
设置为静态变量(使用静态getter和setter)。如果使所有变量都是静态的,那么定义单例实例就没有意义了,因为您只有一个只包含静态变量和方法的类:

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的Elvis引用“有效的Java”。该书中的建议是使用一个成员的枚举实现singleton模式:

public enum Elvis {
  INSTANCE;

  private double weight = 300.;

  public double getWeight() { return weight; }  
  public void setWeight(double weight) { this.weight = weigth; }
}

请注意,由于您通常期望枚举实例是不可变的,所以它在这里看起来有些不标准,权重也不尽相同

OP特别提到了“语义差异”-很明显,有(非?-)语义差异,比如一个是
静态的
,另一个不是…当然可以<代码>静态{instance=new Singleton();}
。我认为“前者”指的是实例变量。此外,不能使用
静态
块初始化实例变量,但可以使用非静态初始值设定块。为了补充赵的评论:
{instance=new Singleton();}
。嗨,如果我指的不是保存Singleton实例本身的变量,而是其他普通数据成员,那么私有实例和私有静态之间有什么区别吗?我也读过Josh Bloch的这部分书,你认为呢,专用静态重量还是专用重量?:DAs我说过,我不喜欢只有静态成员变量和函数的类,所以我会选择非静态的。然而,大多数人认为让所有东西都保持静态可能不是OO,但这不是问题。所以我想这取决于你的类实际在做什么。