为什么要以静态方式访问静态字段?
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 – 实际上从来没有实例调用过)。
快乐的编码。
我并没有真正看到问题标题如何与其他问题匹配:-)更准确和专业的标题增加了问题/答案可能会使其他程序员受益。