如果你有一个像
这样的枚举enum Coffee {
BIG,
SMALL
}
和一个具有类似枚举的实例变量的类:
public class MyClass {
private Coffee coffee;
// Constructor etc.
}
为什么在构造函数中可以说例如coffee.BIG
?
我不明白你可以使用参考?枚举是否将实例变量初始化为null
以外的其他内容?这是第一章SCJP书中的自测题#4。 我试图缩短代码和问题。
答案 0 :(得分:20)
在
enum Coffee {
BIG,
SMALL
}
BIG或SMALL是Coffee类的public static final
个字段,与所有静态字段一样,它们可以通过类名访问,如
Coffee b1 = Coffee.BIG;
或与类相同的引用,如
Coffee s2 = b1.SMALL;
Coffee s3 = Coffee.BIG.SMALL; //BIG is reference of type Coffee so it is OK (but looks strange)
但请记住我们应该避免通过引用访问静态成员。这会造成混淆,因为我们并没有真正访问实例的成员,而是访问类的成员(例如,没有多态行为)。
答案 1 :(得分:13)
这就是在幕后发生的事情:
E:\workspace>type Coffee.java
public enum Coffee {
BIG,
SMALL
}
E:\workspace>javap Coffee
Compiled from "Coffee.java"
public final class Coffee extends java.lang.Enum<Coffee> {
public static final Coffee BIG;
public static final Coffee SMALL;
public static Coffee[] values();
public static Coffee valueOf(java.lang.String);
static {};
}
正如您所看到的,BIG
和SMALL
在您的枚举中基本上是静态字段。
JLS也明确了这一部分:
除了Enum类型E继承自Enum的成员之外, 对于名称为n的每个声明的枚举常量,枚举类型具有 隐式声明了名为n的类型为E的公共静态最终字段 字段被认为是以与。相同的顺序声明 相应的枚举常量,在任何静态字段之前显式 在枚举类型中声明。每个这样的字段都初始化为枚举 与之对应的常数。
希望这能澄清你的问题。
答案 2 :(得分:5)
在Java 5之前,实现枚举的方法是创建一个类,其中私有构造函数和同一类的公共final字段初始化为特定值。
从Java 5开始,enum构造实际上是一个做同样事情的糖,并且不允许处理像null这样的事情,枚举值变成公共静态字段等。