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
访问它们呢?
最后一行是我熟悉的方式
# 1 楼答案
您可以从实例访问static,但这真的很糟糕,因为static与实例的绑定不如与类的绑定
不管书上说什么,不要那样使用静力学。如果您运行checkstyle等,他们也会发出警告:)
顺便说一句,在您的示例中,a为空。它在什么地方初始化了吗
编辑
我知道编译器知道a.DOG绑定到什么,因为静态不能被重写。它不需要a来确定调用,只需要它拥有的编译时类型a
我还知道,即使a是null(我试过了,所以我知道:),这个例子仍然有效
但我还是觉得你能从null中得到东西很奇怪。令人困惑的是:
当我调试NPE时,我会假设a不能为null,因为println工作正常。令人困惑
啊,好的,爪哇。如果你认为你已经看到了这一切,你又得到了另外的东西:)
# 2 楼答案
虽然这样做有效,但不要那样做。将枚举与
Animal.DOG
、Animal.CAT
等一起使用上面所做的是声明一个枚举类型的对象,并在其上引用静态
DOG
。编译器知道a
的类型,并且知道您想要Animal.DOG
。但这会降低可读性我相信这样做的目的是缩短枚举的使用
a.DOG
而不是Animal.DOG
。如果您真的想缩短它,可以使用import static fqn.of.Animal
,然后简单地使用DOG
# 3 楼答案
写入
a.DOG
与写入Animal.DOG
相同。也就是说,编译器将用其编译时类型替换变量。它被认为是坏代码,因为它隐藏了它依赖于编译时类型而不是动态类型a
的事实