Java5新增的特性,一种特殊的类型。本质上是一个类,但是有特殊的约束。这些约束让枚举更简洁、安全。

枚举本质是在一个常量集合,一个属于同一类型的常量集合。比如:四季(春夏秋冬)、星期(一到七)

1.枚举的来由

没有枚举enum时,我们需要定义一组常量,如下:

public class Day {

    public static final int MONDAY =1;

    public static final int TUESDAY=2;

    public static final int WEDNESDAY=3;

    public static final int THURSDAY=4;

    public static final int FRIDAY=5;

    public static final int SATURDAY=6;

    public static final int SUNDAY=7;

}

使用枚举

enum Day {
    MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

枚举对象编译

//反编译Day.class
final class Day extends Enum
{
    //编译器为我们添加的静态的values()方法
    public static Day[] values()
    {
        return (Day[])$VALUES.clone();
    }
    //编译器为我们添加的静态的valueOf()方法,注意间接调用了Enum也类的valueOf方法
    public static Day valueOf(String s)
    {
        return (Day)Enum.valueOf(com/zejian/enumdemo/Day, s);
    }
    //私有构造函数
    private Day(String s, int i)
    {
        super(s, i);
    }
     //前面定义的7种枚举实例
    public static final Day MONDAY;
    public static final Day TUESDAY;
    public static final Day WEDNESDAY;
    public static final Day THURSDAY;
    public static final Day FRIDAY;
    public static final Day SATURDAY;
    public static final Day SUNDAY;
    private static final Day $VALUES[];

    static 
    {    
        //实例化枚举实例
        MONDAY = new Day("MONDAY", 0);
        TUESDAY = new Day("TUESDAY", 1);
        WEDNESDAY = new Day("WEDNESDAY", 2);
        THURSDAY = new Day("THURSDAY", 3);
        FRIDAY = new Day("FRIDAY", 4);
        SATURDAY = new Day("SATURDAY", 5);
        SUNDAY = new Day("SUNDAY", 6);
        $VALUES = (new Day[] {
            MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
        });
    }
}

2 枚举的常用方法

枚举相当于一个集合(数组)

方法名称

返回类型

方法说明

values()

[],枚举数组

返回所有枚举里的数据

ordinal()

int

返回枚举的下标,从0开始

name()

String

返回枚举常量的名称

valuesOf(class,name)

<T extends Enum<T>>

返回带有指定名称的枚举常量

compareTo(E o)

int

比较此枚举与指定对象的顺序

DayEnum[] de = DayEnum.values(); //返回所有枚举里的数据
for (int i = 0; i < de.length; i++) {
    System.out.println("枚举下标位置:" + de[i].ordinal()); //返回枚举的下标
    System.out.println("枚举的名称:" + de[i].name());//返回枚举常量的名称
}

System.out.println(DayEnum.valueOf(DayEnum.class,de[0].name()));//返回带有指定名称的枚举常量
System.out.println(de[0].compareTo(de[1]));//本质通过ordinal()比较

3 枚举的构造函数

定义枚举构造方法,添加对枚举常量的描述。枚举的构造方法只能是私有的

public enum Day2 {

    MONDY("星期一"),
    TUESDAY("星期二"),
    WEDNESDAY("星期三"),
    THURSDAY("星期四"),
    FRIDAY("星期五"),
    SATURDAY("星期六"),
    SUNDAY("星期七");

    private String desc;
    private Day2(String desc){//构造方法
        this.desc = desc;
    }

    public String getDesc() {//普通方法
        return desc;
    }
}

4 枚举中的方法

普通方法

同3.3getDesc(),与普通方法没有区别

public String getDesc() {//普通方法
    return desc;    
}

重写方法

所有枚举的父类均为Enum类,但Enum类的方法除了toString(),均为final方法,不能被重写

@Override
public String toString() {
    return desc;
}

抽象方法

枚举类也可以定义抽象方法,但是每个枚举都需要重写该抽象方法

public enum Day3 {
    MONDAY("星期一"){
        @Override
        public String getInfo() {
            return "";
        }
    };
    Day3(String desc){
        this.desc = desc;
    }
    private String desc;
    public abstract String getInfo();//抽象方法
}


 


5 枚举与接口

Java为单继承,所有enum都集成抽象类Enum,所以enum只能实现接口

枚举实现接口使用场景:菜单,所有菜品均属于Food类型,但是菜单又分为appetizer(开胃菜)、mainCourse(主菜)、dessert(点心)、Coffee等等

public interface Food {
    enum Appetizer implements Food {
        SALAD, SOUP, SPRING_ROLLS;
    }
    enum MainCourse implements Food {
        LASAGNE, BURRITO, PAD_THAI,
        LENTILS, HUMMOUS, VINDALOO;
    }
    enum Dessert implements Food {
        TIRAMISU, GELATO, BLACK_FOREST_CAKE,
        FRUIT, CREME_CARAMEL;
    }
    enum Coffee implements Food {
        BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,
        LATTE, CAPPUCCINO, TEA, HERB_TEA;
    }
}