Java 为什么静态字段应该以静态方式访问?

Java 为什么静态字段应该以静态方式访问?,java,static,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;

这是指..我们无法回复或评论任何内容,因此创建了一个新的。为什么我的

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);
    }
 }
}
发出警告静态字段MyUnits.MILLSECONDS是否应以静态方式访问?
谢谢。

因为当您访问静态字段时,您应该在类(或者在本例中是枚举)上执行此操作。如

不像在中那样在实例上

MyUnits.MILLISECONDS;
编辑以解决为什么的问题:在Java中,当您将某个对象声明为
静态
时,您是说它是类的一个成员,而不是对象(因此为什么只有一个)。因此,在对象上访问它没有意义,因为特定的数据成员与类关联。

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

javac将“接受”它,但它实际上应该是
MyUnits.millizes
(或者在适用范围内不加前缀)

1实际上,javac将代码“重写”为首选形式——如果
m
恰好是
null
它不会在运行时抛出NPE——它永远不会在实例上实际调用)

快乐编码



我真的看不出问题标题如何与其他标题相匹配:-)更准确、更专业的标题会增加问题/答案对其他程序员有益的可能性。

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

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

m.MILLISECONDS;
直接访问静态变量:

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

public class B extends A {
    public static String VALUE = "Bbb";
}
使用实例进行间接访问(给出编译器警告,指出应静态访问值):

到目前为止,很好,编译器可以猜测使用哪一个静态变量,超类上的那个变量在某种程度上更遥远,似乎在某种程度上是合乎逻辑的

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

new B().VALUE (="Bbb")
让我们从B中移除静态变量,并观察以下情况:

  • B实现C,D
  • B扩展A实现C
  • B扩展了A和C,D
  • B扩展A实现C
    ,其中
    A实现D
  • B扩展A实现C
    ,其中
    C扩展D
语句
new B().VALUE
现在是不明确的,因为编译器无法确定哪一个静态变量的意思,并将其报告为错误:

错误:对值的引用不明确
C中的变量值和D中的变量值都匹配


这正是静态变量应该以静态方式访问的原因。

我更改了标题,即“Java代码优化”。请多注意题目。我的错,下次会注意:)是的。。。但是为什么静态字段应该以静态方式访问?!如果我使用的类在静态方法中扮演重要角色,那么这就是一个问题。如果我使用的是新对象().getClass().GetEnclosuringClass();但是这个班的成员也是对象不是吗?!在我看来,这应该是正确的答案,它说明了为什么它是危险的。@ChrisThompson对“为什么”的回答只是“它没有意义——你宣布它是静态的,所以用它作为静态的”——这个答案实际上为为什么它是一个坏做法值得一个具体的坏结果提供了理由。我同意这个答案比公认的答案更有帮助。所以,它并不总是像我猜想的那样工作!不过还是很棒。最后,我想接下来的一个有趣的问题是:为什么一开始就可以从实例中访问静态字段或方法?上面在这个答案中解释的情况最适合这个问题。这更有意义。。真知灼见。
A.VALUE (="Aaa")
B.VALUE (="Bbb")
new B().VALUE (="Bbb")
public interface C {
    public static String VALUE = "Ccc";
}

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