首页 > 代码库 > 详解枚举
详解枚举
一、本节主要点
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; }}
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类型,所以不能被继承。
- 枚举可以实现其他接口