枚举的内部实现

枚举类型的内部实现

// 定义一周七天的枚举类型
public enum WeekDay {
  Mon, Tue, Wed, Thu, Fri, Sat, Sun
}

经过反编译(javap WeekDay 命令)之后得到的内容如下(去掉了汇编代码):

public final class WeekDay extends java.lang.Enum{
    public static final WeekDay Mon;
    public static final WeekDay Tue;
    public static final WeekDay Wed;
    public static final WeekDay Thu;
    public static final WeekDay Fri;
    public static final WeekDay Sat;
    public static final WeekDay Sun;
    static {};
    public static void printDay(int);
    public java.lang.String getDay();
    public static WeekDay[] values();
    public static WeekDay valueOf(java.lang.String);
}

如上结果可见,枚举类型内置了 values 方法来获取全部的枚举值,也可以使用 valueOf 方法来从枚举值的描述信息中去获取某个枚举值对象。前文使用的 day 即会成为构造枚举对象时候的构造参数,我们也可以添加更多的构造参数:

public class Test {

  public enum Color {
    RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
    // 成员变量
    private String name;
    private int index;

    // 构造方法
    private Color(String name, int index) {
      this.name = name;
      this.index = index;
    }

    // 覆盖方法
    @Override
    public String toString() {
      return this.index + "_" + this.name;
    }
  }

  public static void main(String[] args) {
    System.out.println(Color.RED.toString());
  }
}

如果枚举类型的描述值数目或类型与成员变量不一致,那么在编译阶段就会抛出异常。我们也可以自定义 Get/Set 方法来修改枚举值的描述信息,但是这样无法改变枚举值的比较结果,因为枚举值是直接进行引用比较而非值比较。

public enum Color {
    // ...

    // 构造方法
    private Color(String name, int index) {
        this.name = name;
        this.index = index;
    }

    // 普通方法
    public static String getName(int index) {
        for (Color c : Color.values()) {
            if (c.getIndex() == index) {
                return c.name;
            }
        }
        return null;
    }

    // get set 方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }
}