有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java:访问枚举(enum)中的常量

阅读SCJP的书,我在第一章“自我测试”中发现了类似的内容:

enum Animals {
    DOG("woof"), CAT("meow"), FISH("burble");
    String sound;
    Animals(String s) { sound = s; }
}

class TestEnum {      
    static Animals a; 
    public static void main(String[] args) {                                                                                     
        System.out.println(a.DOG.sound + " " + a.FISH.sound);   

        // the following line is from me
        System.out.println(Animals.DOG.sound + " " + Animals.FISH.sound);
    }
} 

注意:代码可以编译。 我不明白的是为什么我们可以从变量a访问DOG、CAT或FISH常量。我认为(这也写在书中)DOG、FISH、CAT作为常量的实现方式类似于public static final Animals DOG = new Animals(1); 那么,如果它们真的是静态的,为什么我们可以从a访问它们呢? 最后一行是我熟悉的方式


共 (3) 个答案

  1. # 1 楼答案

    您可以从实例访问static,但这真的很糟糕,因为static与实例的绑定不如与类的绑定

    不管书上说什么,不要那样使用静力学。如果您运行checkstyle等,他们也会发出警告:)

    顺便说一句,在您的示例中,a为空。它在什么地方初始化了吗

    编辑

    我知道编译器知道a.DOG绑定到什么,因为静态不能被重写。它不需要a来确定调用,只需要它拥有的编译时类型a

    我还知道,即使anull(我试过了,所以我知道:),这个例子仍然有效

    但我还是觉得你能从null中得到东西很奇怪。令人困惑的是:

    Animals a = null;
    System.out.println(a.DOG); // OK
    a.doSomething(); // NullPointerException
    

    当我调试NPE时,我会假设a不能为null,因为println工作正常。令人困惑

    啊,好的,爪哇。如果你认为你已经看到了这一切,你又得到了另外的东西:)

  2. # 2 楼答案

    虽然这样做有效,但不要那样做。将枚举与Animal.DOGAnimal.CAT等一起使用

    上面所做的是声明一个枚举类型的对象,并在其上引用静态DOG。编译器知道a的类型,并且知道您想要Animal.DOG。但这会降低可读性

    我相信这样做的目的是缩短枚举的使用a.DOG而不是Animal.DOG。如果您真的想缩短它,可以使用import static fqn.of.Animal,然后简单地使用DOG

  3. # 3 楼答案

    写入a.DOG与写入Animal.DOG相同。也就是说,编译器将用其编译时类型替换变量。它被认为是坏代码,因为它隐藏了它依赖于编译时类型而不是动态类型a的事实