为什么我们可以通过Java中的对象引用访问静态变量,如下面的代码?
public class Static {
private static String x = "Static variable";
public String getX() {
return this.x; // Case #1
}
public static void main(String[] args) {
Static member = new Static();
System.out.println(member.x); // Case #2
}
}
答案 0 :(得分:3)
以这种方式引用静态变量不是最佳做法。
但是你的问题是为什么允许这样做?我猜测答案是开发人员可以将实例成员(字段或变量)更改为静态成员,而无需更改对该成员的所有引用。
在多开发人员环境中尤其如此。否则,您的代码可能无法编译,因为您的合作伙伴将某些实例变量更改为静态变量。
答案 1 :(得分:2)
之所以被允许,是因为JLS同意了。允许这样做的特定部分是JLS 6.5.6.2(对于member.x
情况)和JLS 15.11.1(在两种情况下)。后者说:
如果该字段是静态的:
如果该字段是非空白的final字段,则结果是作为主表达式类型的类或接口中指定的类变量的值。
如果该字段不是final或空白的final并且字段访问发生在类变量初始值设定项(第8.3.2节)或静态初始值设定项(第8.7节)中,则结果为变量,即,是类中指定的类变量,是主表达式的类型。
JLS为什么允许这些?
坦白说,我不知道。我想不出允许他们使用的任何充分理由。
无论哪种方式,使用引用或this
访问静态变量都是一个坏主意,因为大多数程序员可能会误导您认为您正在使用实例字段。这是不使用Java此功能的重要原因。
在第一种和第二种情况下,应将变量引用为x
或Static.x
而不是member.x
。 (我更喜欢Static.x
。)
答案 2 :(得分:1)
静态变量否则称为类变量,因为它们可用于该类的每个对象。
由于member是Static类的一个对象,所以你可以通过成员对象访问所有静态as作为静态类的非静态变量。
答案 3 :(得分:0)
非静态成员是实例成员。静态成员(类范围)无法访问实例成员,因为无法确定哪个实例拥有任何特定的非静态成员。
实例对象总是可以引用静态成员,因为它属于全局(共享)到其实例的类。
答案 4 :(得分:0)
虽然这不是有趣的做法,但从逻辑上讲还是有道理的。静态变量通常用于在实例化期间强制执行变量的单个声明。 Object是具有其他名称的Class的新副本。即使对象是类的新副本,它仍然具有(未实例化)类(第一个不可见实例)的特征。因此,新对象还具有指向原始副本的静态成员。要注意的是:StackOverflow的新实例也是StackOverflow。