为什么要以静态方式访问静态字段?

时间:2011-04-12 23:35:07

标签: java static

public enum MyUnits
{
    MILLSECONDS(1, "milliseconds"), SECONDS(2, "seconds"),MINUTES(3,"minutes"), HOURS(4, "hours");

    private MyUnits(int quantity, String units)
    {
        this.quantity = quantity;
        this.units = units;
    }

    private int quantity;
    private  String units;

 public String toString() 
 {
    return (quantity + " " + units);
 }

 public static void main(String[] args) 
 {
    for (MyUnits m : MyUnits.values())
    {
        System.out.println(m.MILLSECONDS);
        System.out.println(m.SECONDS);
        System.out.println(m.MINUTES);
        System.out.println(m.HOURS);
    }
 }
}

这是指post ..之后能够回复或评论任何如此创建的新版本。为什么是我的

System.out.println(m.MILLSECONDS);

发出警告 - 静态字段MyUnits.MILLSECONDS应该以静态方式访问? 感谢。

3 个答案:

答案 0 :(得分:98)

因为当你访问静态字段时,你应该在类上(或者在这种情况下是枚举)。如在

MyUnits.MILLISECONDS;

不在

中的实例上
m.MILLISECONDS;

编辑要解决 why 的问题:在Java中,当您将某些内容声明为static时,您说它是该类的成员而不是对象(因此只有一个)。因此,在对象上访问它是没有意义的,因为该特定数据成员与该类相关联。

答案 1 :(得分:60)

实际上有一个很好的理由:
出于含糊不清的原因,非静态访问并不总是有效

假设我们有两个类,A和B,后者是A的子类,静态字段具有相同的名称:

public class A {
    public static String VALUE = "Aaa";
}

public class B extends A {
    public static String VALUE = "Bbb";
}

直接访问静态变量:

A.VALUE (="Aaa")
B.VALUE (="Bbb")

使用实例进行间接访问(提供编译器警告,应静态访问VALUE):

new B().VALUE (="Bbb")

到目前为止,非常好,编译器可以猜出要使用哪个静态变量,超类中的那个静态变量在某种程度上更远,看起来似乎是合乎逻辑的。

现在变得棘手:接口也可能有静态变量。

public interface C {
    public static String VALUE = "Ccc";
}

public interface D {
    public static String VALUE = "Ddd";
}

让我们从B中删除静态变量,并观察以下情况:

  • B implements C, D
  • B extends A implements C
  • B extends A implements C, D
  • B extends A implements C其中A implements D
  • B extends A implements C其中C extends D
  • ...

语句new B().VALUE现在不明确,因为编译器无法确定哪个静态变量,并将其报告为错误:

  

错误:对VALUE的引用含糊不清
  C中的变量VALUE和D匹配的变量VALUE

这就是为什么静态变量应该以静态方式访问的原因。

答案 2 :(得分:10)

因为...它(MILLISECONDS)是一个静态字段(隐藏在枚举中,但它就是这样)...但是它是在实例上调用的给定的类型(但见下文,因为这不是真的真的 1 )。

javac会“接受”那个,但它应该是MyUnits.MILLISECONDS(或在适用范围内没有前缀)。

1 实际上,javac将代码“重写”为首选形式 - 如果m碰巧是null,它不会在运行时抛出NPE - - 它实际上从未在实例上调用过。

快乐的编码。


我并没有真正看到问题标题如何适应其余部分:-)更准确和专业的标题增加了问题/答案可能使其他程序员受益的可能性。