枚举 枚举
enum:关键字enum可以将一组具名的值的有限集合创建成为一种新的类型。
1.枚举的简单使用
1 enum EnumDemo{ 2 RED,YELLOW,GREEN //enum实例 3 } 4 5 public class EnumClass { 6 7 public static void main(String[] args) { 8 for (EnumDemo s : EnumDemo.values()) { 9 System.out.println(s+" ordinal "+s.ordinal()); 10 System.out.println(s.getDeclaringClass());//属于的enm类 11 System.out.println(s.name()); 12 System.out.println("----------"); 13 } 14 } 15 16 }
结果输出:
RED ordinal 0 class EnumDemo RED ---------- YELLOW ordinal 1 class EnumDemo YELLOW ---------- GREEN ordinal 2 class EnumDemo GREEN ----------
从结果可能觉得很奇怪,定义了一个枚举,如果把它看做一个类的话,为什么可以调用values()、ordinal()方法,这些方法我们自己从未定义。这些方法哪里来的呢?实际上是在创建枚举的时候,编译器为我们生成一个相关的类,这个类继承了java.lang.Enum类,这个类提供许多方法。enum除了不能被继承之外,基本上可以将enum看做一个常规的类,我们也可以在enum中添加方法,enum甚至可以有main方法。不过在向enum添加方法前必须在实例序列的最后添加一个分号,同时要求必须先定义enum实例,在定义实例之前定义任何方法和属性都是引起编译报错
2.在switch中使用enum
一般来说,在switch中只能使用整数值,枚举实例天生具备整数值次序,并且可以通过ordinal()方法获取其次序。在Thinking in java中有一个经典的例子:
1 enum Signal{ 2 RED,YELLOW,GREEN;
3 } 4 public class TrafficLight { 5 Signal color = Signal.RED; 6 public void change(){ 7 switch (color) { 8 case RED: 9 color = Signal.GREEN; 10 break; 11 case GREEN: 12 color = Signal.YELLOW; 13 break; 14 case YELLOW: 15 color = Signal.RED; 16 } 17 } 18 19 public String toString(){ 20 return "The traffic light is " +color; 21 } 22 public static void main(String[] args) { 23 TrafficLight t = new TrafficLight(); 24 for(int i=0;i<3;i++){ 25 System.out.println(t); 26 t.change(); 27 } 28 } 29 30 }
结果输出:
The traffic light is RED
The traffic light is GREEN
The traffic light is YELLOW
3.values()的特殊之处
编译器会为我们创建enum类,并且这个类继承Enum类,查看源码发现Enum中并没有values()方法,那么values()哪里来的?以及生成的类到底是什么样子呢。通过javap 反编译字节码文件就可以看到相关的属性和行为。
可以看出values是是编译器插入到生成的类中的一个静态方法,并不是继承来自Enum类,同时编译器还添加了valueOf()方法,这个方法与Enum中的valueOf方法重名,参数不一样。由于java的单继承机制,enum是不能再继承其他类,不过它却可以实现一个或多个接口