Java 构建类型安全的枚举类型

在《Java编程思想-网络版》一书中看到一段有意思的代码。

先来看一段Java实现C/C++枚举效果的非类型安全的版本:

public interface Months {
    int JANUARY = 1, 
        FEBRUARY = 2,
        MARCH = 3,
        APRIL = 4,
        ... ...;
}

上面的代码实际上是在利用Java中interface的成员变量会自动成为public static final的事实,这样我们可以使用Months.JANUARY的方法来引用这些值。但是这个方法的缺陷是非类型安全的,因为我们最终获得的其实是个int。这种方法带来的好处只是减少了硬编码。

接下来看看Bruce Eckel提供的类型安全的版本:

public final class Month2 {
    private String name;

    private Month2(String nm) { 
        name = nm; 
    }

    public String toString() {
        return name; 
    }

    public final static Month2
        JAN = new Month2("January"),
        FEB = new Month2("February"),
        MAR = new Month2("March"),
        APR = new Month2("April"),
        MAY = new Month2("May"),
        JUN = new Month2("June"),
        JUL = new Month2("July"),
        AUG = new Month2("August"),
        SEP = new Month2("September"),
        OCT = new Month2("October"),
        NOV = new Month2("November"),
        DEC = new Month2("December");

    public final static Month2[] month = {
        //这里使用2个JAN是为了填充0号位置,这样数组下标可以跟月份一一对应
        JAN, JAN, FEB, MAR, APR, MAY,
        JUN, JUL, AUG, SEP, OCT, NOV,
        DEC
    }; 
    
    public static void main(String[] args) {
        Month2 m = Month2.JAN;
        System.out.println(m);
        m = Month2.month[12];
        System.out.println(m);
        System.out.println(m == Month2.DEC);
        System.out.println(m.equals(Month2.DEC));
    }
}	

ref: 《Java编程思想-网络版》