通过Java中的对象引用访问静态变量

时间:2012-03-19 05:32:26

标签: java scope static

为什么我们可以通过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
    }   
}

5 个答案:

答案 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此功能的重要原因。

在第一种和第二种情况下,应将变量引用为xStatic.x而不是member.x。 (我更喜欢Static.x。)

答案 2 :(得分:1)

静态变量否则称为类变量,因为它们可用于该类的每个对象。

由于member是Static类的一个对象,所以你可以通过成员对象访问所有静态as作为静态类的非静态变量。

答案 3 :(得分:0)

非静态成员是实例成员。静态成员(类范围)无法访问实例成员,因为无法确定哪个实例拥有任何特定的非静态成员。

实例对象总是可以引用静态成员,因为它属于全局(共享)到其实例的类。

答案 4 :(得分:0)

虽然这不是有趣的做法,但从逻辑上讲还是有道理的。静态变量通常用于在实例化期间强制执行变量的单个声明。 Object是具有其他名称的Class的新副本。即使对象是类的新副本,它仍然具有(未实例化)类(第一个不可见实例)的特征。因此,新对象还具有指向原始副本的静态成员。要注意的是:StackOverflow的新实例也是StackOverflow。