枚举的特点

◆类型安全(Type Safety)
◆紧凑有效的枚举数值定义(Compact, Efficient Declaration of Enumerated Values)
◆无缝的和程序其它部分的交互操作(Seamless integration with other language features)
◆运行的高效率(Runtime efficiency

枚举类型概念
public class EnumDemoOne {  
    private enum InnerEnum {  
        RED, GREEN, YELLOW  
    };  

    public static void main(String[] args) {  
        System.out.println(InnerEnum.RED);  
        System.out.println(InnerEnum.GREEN);  
        System.out.println(InnerEnum.YELLOW);  
    }  
}

运行上面的代码,将编辑产生EnumDemoOne.class和EnumDemoOne$InnerEnum.class。
由此说明定义枚举类型其实就是在定义一个类,只不过很多细节由编译器帮你补齐了,所以,某种程度上enum关键词的作用就像是class或interface.当使用enum定义枚举类型时,实际上所定义出来的类型是继承自Java.lang.Enum类。

PS:我常把InnerEnum叫做枚举类型,把其中的RED等叫做枚举变量或枚举值。


public enum Color {  
    RED{  
        public String getName(){  
            return "红色";  
        }  
    }  
    ,GREEN{  
        public String getName(){  
            return "绿色";  
        }  
    }  
    ,YELLOW{  
        public String getName(){  
            return "黄色";  
        }  
    };  
    public abstract String getName();  
}

如果RED只是一个Color类的一个static final的实例,那么上面的代码就很让了费解了,为什么在枚举类型中可以有一个抽象方法,而每个枚举值可以对其重新实现?
别急,看了我对这个类的测试代码你就明白,测试代码如下:

public class EnumDemoFour{  
    public static void main(String[] args){  
        //打印该枚举值的名称  
        System.out.println(Color.RED.getName());  
        //打印该枚举值的类  
        System.out.println(Color.RED.getClass());  
        //打印该枚举值的类的父类  
        System.out.println(Color.RED.getClass().getSuperclass());  
        //打印该枚举值的类的父类的父类
        System.out.println(Color.RED.getClass().getSuperclass().getSuperclass());  
        //打印该枚举类型的修饰符  
        System.out.println(Modifier.toString(Color.class.getModifiers()));  
    }     
    /*运行结果 
    红色 
    class com.lxq.enumm.Color$1 
    class com.lxq.enumm.Color 
    class java.lang.Enum 
    public abstract*/  
}
该运行结果首先说明了RED和Color不是同一个类,而是前者是后者的一个子类;同时也说明了enum申明的其实是一个abstract的类,所以Color中可以有抽象方法。
那么,我们应该这么理解枚举类型的原理,首先enum Color继承了Java.lang.Enum这个抽象类,但enum Color还是一个抽象类,所以它可以有抽象方法和非抽象方法。

而enum Color中的枚举值变量RED事实上上Color的一个匿名子类,所以它可以实现Color中的抽象方法,这样,当我们调用System.out.println(Color.RED.getName());
就是调用了匿名子类实现的方法。当然这些过程的很多事都有编译器等为我们做了,所以这里的代码很简单。
要是你不明白上面打印的内容,我再提供一个普通的类给你看看,还是类似的效果哦。

public abstract class TestInnerClass {  
    public abstract void dosomething();  
    public static void main(String[] args){  
        TestInnerClass tic=new TestInnerClass(){  
            @Override  
            public void dosomething() {  
                System.out.println("我是匿名子类");  
            }     
        };  
        tic.dosomething();  
        System.out.println(tic.getClass());  
    }  
    /*输出结果 
    我是匿名子类 
    class TestInnerClass$1 
    */  
}

最后再附上网上一个使用Java普通类模拟枚举的例子,这个例子真的很好。
使用Java普通类模拟枚举

import java.util.HashMap;  
import java.util.Map;  

/** 
 * 模拟星期中的表示的天,每个星期天都表示一个对象 
 * 1、类中的每一个枚举成员都是该类的一个实例对象 
 * 2、构造函数私有化 
 * 3、提供操作枚举成员的抽象方法和静态方法 
 */  
public abstract class WeekDate {  
    /** 
     * 星期一 
     */  
    public static final WeekDate MON = new WeekDate("MON",0) {//匿名子类  
        @Override  
        public WeekDate nextDay() {  
            return TUES;  
        }  
        @Override  
        public WeekDate preDay() {  
            return SUN;  
        }  
        @Override  
        public String toString() {  
            return "WeekDate.MON";  
        }  
    };    

    /** 
     * 星期二 
     */  
    public static final WeekDate TUES = new WeekDate("TUES",1) {  
        @Override  
        public WeekDate nextDay() {  
            return WEDNES;  
        }  
        @Override  
        public WeekDate preDay() {  
            return MON;  
        }  
        @Override  
        public String toString() {  
            return "WeekDate.TUES";  
        }  
    };  

    /** 
     * 星期三 
     */  
    public static final WeekDate WEDNES = new WeekDate("WEDNES",2) {  
        @Override  
        public WeekDate nextDay() {  
            return THURS;  
        }  
        @Override  
        public WeekDate preDay() {  
            return TUES;  
        }  
        @Override  
        public String toString() {  
            return "WeekDate.WEDNES";  
        }     
    };  

    /** 
     * 星期四 
     */  
    public static final WeekDate THURS = new WeekDate("THURS",3) {  
        @Override  
        public WeekDate nextDay() {  
            return FRI;  
        }  
        @Override  
        public WeekDate preDay() {  
            return WEDNES;  
        }         
        @Override  
        public String toString() {  
            return "WeekDate.THURS";  
        }         
    };  

    /** 
     * 星期五 
     */  
    public static final WeekDate FRI = new WeekDate("FRI",4){  
        @Override  
        public WeekDate nextDay() {  
            return SATUR;  
        }  
        @Override  
        public WeekDate preDay() {  
            return THURS;  
        }  
        @Override  
        public String toString() {  
            return "WeekDate.FRI";  
        }  
    };  

    /** 
     * 星期六 
     */  
    public static final WeekDate SATUR = new WeekDate("SATUR",5){  
        @Override  
        public WeekDate nextDay() {  
            return SUN;  
        }  
        @Override  
        public WeekDate preDay() {  
            return FRI;  
        }         
        @Override  
        public String toString() {  
            return "WeekDate.SATUR";  
        }         
    };  

    /** 
     * 星期日 
     */  
    public static final WeekDate SUN = new WeekDate("SUN",6){  
        @Override  
        public WeekDate nextDay() {  
            return MON;  
        }  
        @Override  
        public WeekDate preDay() {  
            return SATUR;  
        }  
        @Override  
        public String toString() {  
            return "WeekDate.SUN";  
        }  
    };  

    private static Map<String, WeekDate> valueMap = new HashMap<String, WeekDate>();  

    /** 
     * 枚举名称 
     */  
    private final String name;  

    /** 
     * 枚举成员的顺序 
     */  
    private final int ordinal;  

    private WeekDate(String name,int ordinal) {  
        this.name = name;  
        this.ordinal = ordinal;  
    }  

    /** 
     * 保存枚举成员 
     */  
    private static WeekDate[] values = {  
        MON,TUES,WEDNES,THURS,FRI,SATUR,SUN  
    };  

    //初始化  
    static {  
        valueMap.put("MON", values[0]);  
        valueMap.put("TUES", values[1]);  
        valueMap.put("WEDNES", values[2]);  
        valueMap.put("THURS", values[3]);  
        valueMap.put("FRI", values[4]);  
        valueMap.put("SATUR", values[5]);  
        valueMap.put("SUN", values[6]);  
    }  

    /** 
     * 下一天 
     * @return 
     */  
    public abstract WeekDate nextDay();  

    /** 
     * 前一天 
     * @return 
     */  
    public abstract WeekDate preDay();  

    /** 
     * 枚举中的所有成员 
     * @return 
     */  
    public static WeekDate[] values() {  
        return values;  
    }  

    /** 
     * 将一个字符串转换成一个枚举成员对象 
     * @param name 枚举名称 
     * @return 枚举对象 
     */  
    public static WeekDate valueOf(String name) {  
        if (name.equalsIgnoreCase("MON")) {  
            return MON;  
        } else if (name.equalsIgnoreCase("TUES")) {  
            return TUES;  
        } else if (name.equalsIgnoreCase("WEDES")) {  
            return WEDNES;  
        } else if (name.equalsIgnoreCase("THURS")) {  
            return THURS;  
        } else if (name.equalsIgnoreCase("FRI")) {  
            return FRI;  
        } else if (name.equalsIgnoreCase("SATUR")) {  
            return SATUR;  
        } else if (name.equalsIgnoreCase("SUN")) {  
            return SUN;  
        } else {  
            throw new IllegalArgumentException("找不到" + name + "枚举类型!");  
        }  
    }  

    /** 
     * 优化字符串转枚举对象 
     * @param name 枚举名称 
     * @return 枚举对象 
     */  
    public static WeekDate valueOf_2(String name) {  
        WeekDate value = valueMap.get(name.toUpperCase());  
        if (value == null) {  
            throw new IllegalArgumentException("找不到" + name + "枚举类型!");  
        }  
        return value;  
    }  
    public String getName() {  
        return name;  
    }  
    public int getOrdinal() {  
        return ordinal;  
    }  
}

使用JDK5.0中提供的枚举特性

/** 
 * 枚举的应用 
 * 存储每周中的天份 
 */  
public enum WeekDateEnum {  

    MON {  

        @Override  
        public WeekDateEnum nextDay() {  
            return TUES;  
        }  

        @Override  
        public WeekDateEnum preDay() {  
            return SUN;  
        }  

    },  TUES {  

        @Override  
        public WeekDateEnum nextDay() {  
            return WEDNES;  
        }  

        @Override  
        public WeekDateEnum preDay() {  
            return MON;  
        }  

    },  WEDNES {  

        @Override  
        public WeekDateEnum nextDay() {  
            return THURS;  
        }  

        @Override  
        public WeekDateEnum preDay() {  
            return TUES;  
        }  

    },  THURS {  

        @Override  
        public WeekDateEnum nextDay() {  
            return FRI;  
        }  

        @Override  
        public WeekDateEnum preDay() {  
            return WEDNES;  
        }  

    },  FRI {  

        @Override  
        public WeekDateEnum nextDay() {  
            return SATUR;  
        }  

        @Override  
        public WeekDateEnum preDay() {  
            return THURS;  
        }  

    },  SATUR {  

        @Override  
        public WeekDateEnum nextDay() {  
            return SATUR;  
        }  

        @Override  
        public WeekDateEnum preDay() {  
            return FRI;  
        }  

    },  SUN {  

        @Override  
        public WeekDateEnum nextDay() {  
            return SATUR;  
        }  

        @Override  
        public WeekDateEnum preDay() {  
            return MON;  
        }  

    };  

    private WeekDateEnum() {}  

    /** 
     * 下一天 
     * @return 
     */  
    public abstract WeekDateEnum nextDay();  

    /** 
     * 前一天 
     * @return 
     */  
    public abstract WeekDateEnum preDay();  

    /** 
     * 枚举对象公共的toString方法,可以在case块中反馈自己想要返回的信息 
     */  
    public String toString() {  
        switch (this) {  
        case MON:  
            return "WeekDateEnum.MON";  
        case TUES:  
            return "WeekDateEnum.TUES";  
        case WEDNES:  
            return "WeekDateEnum.WEDNES";  
        case THURS:  
            return "WeekDateEnum.THURS";  
        case FRI:  
            return "WeekDateEnum.FRI";  
        case SATUR:  
            return "WeekDateEnum.SATUR";  
        case SUN:  
            return "WeekDateEnum.SUN";  
        default:  
            return null;  
        }  
    }  
}

枚举功能测试

/** 
 * 枚举功能测试 
 */  
public class EnumTest {  

    public static void main(String[] args) {  

        //使用普通JAVA类模拟枚举的应用  
        WeekDate weekDate = WeekDate.MON;       //获得一个枚举对象  
        //调用枚举中提供的方法  
        System.out.println(weekDate.nextDay());   
        System.out.println(weekDate.preDay());  
        System.out.println(weekDate.getName());  
        //获得枚举成员所在枚举成员列表中的位置  
        System.out.println(weekDate.getOrdinal());  
        //调用某一个枚举成员的方法  
        System.out.println(WeekDate.values()[0].preDay());  
        System.out.println("---------------遍历枚举成员,普通JAVA类模拟--------------------------");  
        for (WeekDate weekDate2 : WeekDate.values()) {  
            System.out.println(weekDate2);  
        }  

        System.out.println("\n=================================================================\n");  

        //使用JDK中提供的枚举特性功能应用  
        WeekDateEnum weekDateEnum = WeekDateEnum.MON;   //获得一个枚举对象  
        System.out.println(WeekDate.values().length);   //获得枚举成员数量  
        System.out.println(weekDateEnum.name());        //获得枚举的字符串名称  
        System.out.println(weekDateEnum.toString());    //打印枚举对象,已重写toString方法,默认打印枚举的名称  
        System.out.println(weekDateEnum.nextDay().ordinal());   //枚举成员列表中的位置  
        System.out.println(WeekDateEnum.valueOf("FRI").nextDay().ordinal());  
        System.out.println("---------------遍历枚举成员,使用JDK的枚举特性-------------------------");  
        for (WeekDateEnum enumDemo : WeekDateEnum.values()) {  
            System.out.println(enumDemo);  
        }  

    }   

}