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

2022-09-04 20:58:51

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

答案 1

通常,每个人都可以访问公共变量,而私有变量只能从类的当前实例中访问。在示例中,允许从该方法访问变量,因为该方法位于 Static 类中。xmain

如果你想知道为什么允许你从另一个静态类的实例访问它,而不是你当前所在的实例(通常不允许私有变量使用),那只是因为静态变量不是基于每个实例,而是基于每个类。这意味着可以从 A 的所有实例访问 A 的相同静态变量。

如果不是这种情况,那么根本没有人能够访问私有静态变量,因为它不属于一个实例,而是全部实例。


答案 2

它被允许的原因是JLS说它是。允许这样做的特定部分是JLS 6.5.6.2(对于这些情况)和JLS 15.11.1(在这两种情况下)。后者说:member.x

如果字段是静态的:

  • 如果该字段是非空白的最终字段,则结果是作为主表达式类型的类或接口中指定类变量的值。

  • 如果字段不是最终的,或者是空白的最终字段,并且字段访问发生在类变量初始值设定项 (§8.3.2) 或静态初始值设定项 (§8.7) 中,则结果是一个变量,即作为主表达式类型的类中的指定类变量。


为什么JLS允许这些?

坦率地说,我不知道。我想不出任何好的理由允许他们。

无论哪种方式,使用引用或访问静态变量都是一个坏主意,因为大多数程序员可能会被误导,认为您正在使用实例字段。这是不使用Java的这一特性的有力理由。this

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