枚举实例变量(Enum as instance variables)

2019-07-30 18:45发布

如果你有一个枚举如

enum Coffee {
    BIG,
    SMALL
}

并且具有这样的枚举的实例变量的类:

public class MyClass {
    private Coffee coffee;

    // Constructor etc.
}

为什么有可能在构造函数中说,如coffee.BIG ? 我不明白,你可以使用的参考? 是枚举实例变量初始化为比其他一些null ? 它是SCJP书的第一章的自检问题#4。 我试图缩短了代码和问题。

Answer 1:

enum Coffee {
    BIG,
    SMALL
}

或大或小的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)

但让记住, 我们应该避免通过引用访问静态成员 。 这造成混乱,因为我们并没有真正访问实例的成员,但的成员(因此例如没有多态)。



Answer 2:

这是幕后发生的事情:

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也使这部分明确:

除此之外枚举类型E从枚举继承,对每个申报枚举名称为常值N的成员,枚举类型有一个隐式声明的E型的公共静态最终命名为N字段,这些字段被认为是在被宣布相同的顺序,相应的枚举常量,在任何静态字段的枚举类型显式声明。 每个这样的字段被初始化为对应于它的枚举常量。

希望这阐明你的问题。



Answer 3:

Java 5中实现枚举的方式之前,创建具有私有构造函数初始化和对特定值的相同类的公共领域的最后一课。

由于Java 5,枚举结构实际上是一种糖,做同样的,也照顾之类的东西空值是不允许的,枚举值将成为公共静态字段等。



文章来源: Enum as instance variables
标签: java enums scjp