枚举作为实例变量

时间:2012-08-04 12:58:39

标签: java enums scjp

如果你有一个像

这样的枚举
enum Coffee {
    BIG,
    SMALL
}

和一个具有类似枚举的实例变量的类:

public class MyClass {
    private Coffee coffee;

    // Constructor etc.
}

为什么在构造函数中可以说例如coffee.BIG? 我不明白你可以使用参考?枚举是否将实例变量初始化为null以外的其他内容?这是第一章SCJP书中的自测题#4。 我试图缩短代码和问题。

3 个答案:

答案 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 {};
}

正如您所看到的,BIGSMALL在您的枚举中基本上是静态字段。

JLS也明确了这一部分:

  

除了Enum类型E继承自Enum的成员之外,   对于名称为n的每个声明的枚举常量,枚举类型具有   隐式声明了名为n的类型为E的公共静态最终字段   字段被认为是以与。相同的顺序声明   相应的枚举常量,在任何静态字段之前显式   在枚举类型中声明。每个这样的字段都初始化为枚举   与之对应的常数。

希望这能澄清你的问题。

答案 2 :(得分:5)

在Java 5之前,实现枚举的方法是创建一个类,其中私有构造函数和同一类的公共final字段初始化为特定值。

从Java 5开始,enum构造实际上是一个做同样事情的糖,并且不允许处理像null这样的事情,枚举值变成公共静态字段等。