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

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 .. wasnt能够回复或评论任何如此创build一个新的。 为什么是我的

 System.out.println(m.MILLSECONDS); 

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

因为当你访问一个静态字段时,你应该在类上(或者在这个例子中是enum)这样做。 如在

 MyUnits.MILLISECONDS; 

不在一个实例中

 m.MILLISECONDS; 

编辑为了解决这个问题的原因 :在Java中,当你声明为static东西时,你说它是类的成员,而不是对象(因此为什么只有一个)。 因此,在对象上访问它是没有意义的,因为该特定的数据成员与类相关联。

其实有一个很好的理由:
出于不明确的原因,非静态访问并不总是有效的

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

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

直接访问静态variables:

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

使用实例进行间接访问(给编译器警告VALUE应该被静态访问):

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

到目前为止,编译器可以猜测出哪个静态variables可以使用,超类中的那个变得更远,似乎是合乎逻辑的。

现在到了棘手的地步:接口也可以有静态variables。

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

让我们从B中移除静态variables,并观察以下情况:

  • 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的语句new B().VALUE现在是不明确的 ,因为编译器不能决定哪个静态variables的意思 。 这正是静态variables应该以静态方式访问的原因。

因为它( MILLISECONDS )是一个静态字段(隐藏在一个枚举中,但它就是这样)…但是它是在给定types的实例上调用的(但是由于这不是真的 1 )。

javac将“接受”,但它确实应该是MyUnits.MILLISECONDS (或在适用范围中没有前缀)。

1实际上,javac将代码“重写”为首选的forms – 如果m碰巧是null它不会在运行时抛出NPE – 实际上从来没有实例调用过)。

快乐的编码。


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