首页 > 代码库 > 详解枚举

详解枚举

一、本节主要点

1、 什么是枚举;

2、 枚举的特征;

3、 枚举的常用方法;

4、总结;

二、枚举的概念

     枚举,简单来说,就是把 变量的值一一列出来,这些值必须在列举的范围内。Java 在5.0版本才开始支持枚举类型的。

      那我就想知道它5.0 之前,没有枚举的时候,是如何处理枚举能解决的问题的?

  2.1 假设一个需求

       根据一个输入参数,可以知道它是星期几。

  2.2 程序实现

package com.panpan.web.domain.meiju;/**  JDK 5.0 之前的实现 * Created by hp on 14-7-20. */public class OldMei {    public void printDay(int day) {        switch (day) {            case 1:                System.out.println("今天是星期一,上班");                break;            case 2:                System.out.println("今天是星期二,上班");                break;            case 3:                System.out.println("今天是星期三,上班");                break;            case 4:                System.out.println("今天是星期四,上班");                break;            case 5:                System.out.println("今天是星期五,上班");                break;            case 6:                System.out.println("今天是星期六,上班或者不上班");                break;            case 7:                System.out.println("今天是星期日,休息");                break;            default:                System.out.println("哥也不懂今天是星期几了");        }    }    public static void main(String[] args) {        OldMei oldMei = new OldMei();        oldMei.printDay(12);    }}

上述代码虽然能完成我们的需求,同时也有个问题,就是假设我输入7以外的数据,调用者也不懂发生了什么。所以,这个做法的容错性并不好。

2.3 告诉调用者参数不正确

接着上面的程序,我们会想到在default 分支上抛出一个异常。告诉调用者参数不正确。

case 7:                System.out.println("今天是星期日,休息");                break;            default:                throw new ParamsExcepiton();

这样可以解决了。仔细一想,printDay 这样简单的方法同时还要做验证参数的事情。能不能从源头就把不符合规范的参数排除了呢?

2.4 枚举告诉你,这可以

public void printDay(DayEnum day){        switch (day) {            case MONDAY:                System.out.println("今天是星期一,上班");                break;            case TUESDAY:                System.out.println("今天是星期二,上班");                break;            case WEDNESDAY:                System.out.println("今天是星期三,上班");                break;            case THURSDAY:                System.out.println("今天是星期四,上班");                break;            case FRIDAY:                System.out.println("今天是星期五,上班");                break;            case SATURDAY:                System.out.println("今天是星期六,上班或者不上班");                break;            case SUNDAY :                System.out.println("今天是星期日,休息");                break;        }    }    public static void main(String[] args) {        OldMei oldMei = new OldMei();        oldMei.printDay(DayEnum.FRIDAY);    }

这样做之后,你会发现只能给printDay 枚举中的参数了。实现了在入参时期进行规则校验的目的。

三、枚举的特征

如上,DayEnum 就是class,而且是一个不可以被继承的final类。所以这些就是 public static final 的变量。

既然是class ,那就有构造器,方法啊,域的。它的构造器只能私有private,可以保证外部代码无法构造新的实例。

3.1 所有枚举类都继承了Enum的方法。

(1)ordinal() , 返回枚举中顺序

public final int ordinal() {    return ordinal;    }

(2)compareTo() ,返回两个枚举顺序之差。

int i = DayEnum.MONDAY.compareTo(DayEnum.FRIDAY);        System.out.println(i);

(3)values(),返回全部枚举值的数组。

 

等等,还有valueOf,toString。不一一介绍了。

 

四、一些用法

(1) 枚举中的普通方法

package com.panpan.web.domain.meiju;/** * Created by hp on 14-7-20. */public enum DayEnum {    MONDAY("1","星期一"),    TUESDAY("2","星期二"),    WEDNESDAY("3","星期三"),    THURSDAY("4","星期四"),    FRIDAY("5","星期五"),    SATURDAY("6","星期六"),    SUNDAY("7","星期日")   ;    private String index;    private String description;    DayEnum(String index, String description) {        this.index = index;        this.description = description;    }     // 普通方法    public DayEnum geDayEnum(String index) {        DayEnum[] values = DayEnum.values();        for (DayEnum value : values) {            if (value.getIndex().equals(index)) {                return value;            }        }        return null;    }    public String getIndex() {        return index;    }    public void setIndex(String index) {        this.index = index;    }    public String getDescription() {        return description;    }    public void setDescription(String description) {        this.description = description;    }}

通过普通方法,你只要调用getDayEnum(),就可以知道是哪个DayEnum 。再也不用冗长的if,else 了。

(2)实现接口

public enum DayEnum implements SayHelloWorld{    MONDAY("1","星期一"),    TUESDAY("2","星期二"),    WEDNESDAY("3","星期三"),    THURSDAY("4","星期四"),    FRIDAY("5","星期五"),    SATURDAY("6","星期六"),    SUNDAY("7","星期日")   ;    private String index;    private String description;    DayEnum(String index, String description) {        this.index = index;        this.description = description;    }     @Override     public void sayHi() {         System.out.println("hello wo am panpan");     }    @Override    public void goodBye() {        System.out.println("good bye");    }    public String getIndex() {        return index;    }    public void setIndex(String index) {        this.index = index;    }    public String getDescription() {        return description;    }    public void setDescription(String description) {        this.description = description;    }}
(3)接口中使用枚举类
public interface Color {    enum Hot implements Color{        RED,YELLOW    }}

其实就相当于定义一个常量。

 

(4)关于枚举集合的使用(EnumMap 和 EnumSet)

Map<DayEnum,String> eunmMap = new EnumMap<DayEnum,String>(DayEnum.class);        eunmMap.put(DayEnum.FRIDAY, "星期五啦,明天可以玩了,哈哈");        eunmMap.put(DayEnum.SATURDAY, "星期六啦,明天可以玩了,哈哈");

五、小结

枚举虽然不难,但是还是总结一下。

  • 枚举可以约束传入的参数
  • 枚举是一个特殊的类,final类型,所以不能被继承。
  • 枚举可以实现其他接口