Java:访问枚举(enum)中的常量
阅读 SCJP 书,我在第 1 章“自测试”中发现了类似的内容:
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
访问它们? 最后一行是我熟悉的方式。
reading the SCJP book, I've found something like this in the chapter 1 "self-test" :
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);
}
}
Note: the code compile fine.
What I don't understand is why we can access the DOG, CAT or FISH constants from the variable a
. I thought (and it is also written in the book) that the DOG, FISH, CAT being constants are implemented in a way similar to public static final Animals DOG = new Animals(1);
So if they really are static why can we access them from a
?
The last line is the way I am familiar with.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
虽然这可行,但不要这样做。将枚举与
Animal.DOG
、Animal.CAT
等一起使用。上面的作用是声明枚举类型的对象,并引用静态
DOG就可以了。编译器知道
a
的类型,并且知道您想要Animal.DOG
。但这会破坏可读性。我相信这样做的目的是缩短枚举的使用。
a.DOG
而不是Animal.DOG
。如果您确实想缩短它,可以使用import static fqn.of.Animal
,然后简单地使用DOG
。Although this works, don't do it like that. Use enums with
Animal.DOG
,Animal.CAT
, etc.What the above does is declare an object of the enum type, and reference the static
DOG
on it. The compiler knows the type ofa
, and knows that you wantAnimal.DOG
. But this kills readability.I believe the purpose of this is to shorten the usage of enums.
a.DOG
instead ofAnimal.DOG
. If you really want to shorten it, you can useimport static fqn.of.Animal
and then use simplyDOG
.编写
a.DOG
与编写Animal.DOG
相同。也就是说,编译器会将变量替换为其编译时类型 Animal。它被认为是糟糕的代码,因为它隐藏了这样一个事实:它依赖于编译时类型而不是a
的动态类型。Writing
a.DOG
is the same as writingAnimal.DOG
. That is, the compiler will replace the variable with its compile time type Animal. It is considered bad code since it hides the fact that it relies on the compile time type instead of the dynamic type ofa
.您可以从实例访问静态数据,但这确实很糟糕,因为静态数据与实例的绑定程度不如与类的绑定程度。
无论书上怎么说,都不要以这种方式使用静力学。如果您运行 checkstyle 等,它们也会发出警告:)
顺便说一句,在您的示例中 a 为 null。它是否在某处初始化?
编辑
我知道编译器知道 a.DOG 所绑定的内容,因为静态变量无法被覆盖。它不需要a来确定调用,只需要它所具有的a的编译时类型。
我也知道即使 a 为 null,该示例仍然有效(我尝试过,所以我知道:)。
但我仍然认为你可以从 null 获取东西,这很奇怪。这很令人困惑:
当我调试 NPE 时,我会假设 a 不能为 null,因为 println 工作正常。令人困惑。
啊,好吧,Java。如果你认为你已经看完了这一切,你会再次得到其他的东西:)
You can access statics from an instance, but it's really bad taste as statics aren't as much bound to an instance as bound to the class.
Whatever the book says, don't use statics that way. And if you run checkstyle and the like, they warn about it too :)
BTW a is null in your example. Does it get initialized somewhere?
EDIT
I know the compiler knows what a.DOG is bound to, as statics can't be overridden. It does not need a to determine the call, only the compile-time type of a, which it has.
I also know that the example works even though a is null (I tried so I know:).
But I still think it's weird you can get stuff from null. And it's confusing:
When I would be debugging the NPE I would assume that a can't be null as the println worked fine. Confusing.
Ah well, Java. If you think you've seen it all you get something else again :)