Java编程思想学习(十四) 枚举
关键字enum可以将一组具名的值有限集合创建一种为新的类型,而这些具名的值可以作为常规的程序组件使用。
基本enum特性
调用enum的values()方法可以遍历enum实例,values()方法返回enum实例数组,且数组中元素保持在enum声明时的顺序。
1 public class TestEnum { 2 public static void main(String[] args) { 3 Fruit[] values = Fruit.values(); 4 for (Fruit fruit : values) { 5 System.out.println(fruit); 6 printEnum(fruit); 7 } 8 } 9 10 public enum Fruit { 11 APPLE, ORANGE, WATERMELON 12 } 13 14 public static void printEnum(Fruit fruit) { 15 //顺序 16 System.out.println(fruit + " ordinal:" + fruit.ordinal()); 17 //比较(ordinal值) 18 System.out.println("compare to apple" + fruit.compareTo(Fruit.APPLE)); 19 //== 20 System.out.println(fruit == Fruit.ORANGE); 21 //获取所属的enum类 22 System.out.println(fruit.getDeclaringClass()); 23 //获取名字 24 System.out.println(fruit.name()); 25 } 26 } 27 28 //output 29 /** 30 APPLE 31 ORANGE 32 WATERMELON 33 */ 34 35 /** 36 APPLE ordinal:0 37 compare to apple0 38 false 39 class com.TestEnum$Fruit 40 APPLE 41 ORANGE ordinal:1 42 compare to apple1 43 true 44 class com.TestEnum$Fruit 45 ORANGE 46 WATERMELON ordinal:2 47 compare to apple2 48 false 49 class com.TestEnum$Fruit 50 WATERMELON 51 */
ordinal()方法返回int值:表示enum实例在声明时的次序,从0开始。
使用==来比较enum实例。
将静态导入用于enum
使用static import能够将enum实例的标识符带入当前命名空间,无需再用emum类型来修饰enum实例。
import static----> MALE
import----> Gender.MALE
1 package com; 2 3 import static com.Gender.*; 4 5 /** 6 * Created by JohnTsai on 15/10/22. 7 */ 8 public class TestStaticImport { 9 Gender gender; 10 11 public static void main(String[] args) { 12 System.out.println(new TestStaticImport(MALE)); 13 System.out.println(new TestStaticImport(FEMALE)); 14 } 15 16 public TestStaticImport(Gender gender) { 17 this.gender = gender; 18 } 19 20 @Override 21 public String toString() { 22 return "GENDER is" + this.gender; 23 } 24 }
enum中的构造器与方法和普通的类没有区别,除了少数限制外,enum就是一个普通的类。(一般只使用普通的枚举类型)
需先定义enum实例,然后再定义自己的方法。
1 package com; 2 3 /** 4 * Created by JohnTsai on 15/10/23. 5 */ 6 public enum Direction { 7 //最先定义enum实例 8 WEST("this is west"),EAST("this is east"),NORTH("this is north"),SOUTH("this is south"); 9 //要定义自己的方法,需在定义的enum实例后加分号 10 11 private String text; 12 private Direction(String text){ 13 this.text = text; 14 } 15 public String getText(){ 16 return this.text; 17 } 18 19 public static void main(String[] args) { 20 for(Direction direction:Direction.values()){ 21 System.out.println(direction+":"+direction.getText()); 22 } 23 } 24 25 }
覆盖enum的方法
覆盖enum的toString()方法和覆盖一般类的方法没有区别。
switch语句中的enum
enum提供了非常便利的功能:在switch中使用enum。
1 package com; 2 3 /** 4 * Created by JohnTsai on 15/10/23. 5 */ 6 enum Signal { 7 GREEN, YELLOW, RED 8 } 9 10 public class TrafficLight { 11 Signal color = Signal.GREEN; 12 13 public void change() { 14 switch (color) { 15 case RED: 16 color = Signal.GREEN; 17 break; 18 case GREEN: 19 color = Signal.YELLOW; 20 break; 21 case YELLOW: 22 color = Signal.RED; 23 break; 24 } 25 } 26 27 @Override 28 public String toString() { 29 return "traffic light is" + color; 30 } 31 32 public static void main(String[] args) { 33 TrafficLight light = new TrafficLight(); 34 for (int i = 0; i < 10; i++) { 35 System.out.println(light); 36 light.change(); 37 } 38 } 39 }
values()的神秘之处
编译器为我们创建的enum类都继承自Enum类。
但是Enum类中并没有values()方法。
1 package com; 2 3 import java.lang.reflect.Method; 4 import java.lang.reflect.Type; 5 import java.util.Set; 6 import java.util.TreeSet; 7 8 /** 9 * Created by JohnTsai on 15/10/25. 10 */ 11 enum Explore{ 12 HERE,THERE 13 } 14 public class Reflection { 15 public static Set<String> analyse(Class<?> enumClass){ 16 println("Analyzing begin:"); 17 println("Interfaces:"); 18 for(Type t:enumClass.getGenericInterfaces()){ 19 print(t.toString()); 20 } 21 println("Base:"+enumClass.getSuperclass()); 22 println("Methods:"); 23 Set<String> methods = new TreeSet<>(); 24 for(Method m:enumClass.getMethods()){ 25 methods.add(m.getName()); 26 } 27 println(methods.toString()); 28 return methods; 29 } 30 31 32 public static void println(String s){ 33 System.out.println(s); 34 } 35 36 public static void print(String s){ 37 System.out.print(s); 38 } 39 40 public static void main(String[] args) { 41 Set<String> exploreMethods = analyse(Explore.class); 42 Set<String> enumMethods = analyse(Enum.class); 43 println("Explore containsAll(Enum)?"+exploreMethods.containsAll(enumMethods)); 44 println("Explore removeAll(Enum)"+exploreMethods.removeAll(enumMethods)); 45 46 println(exploreMethods.toString()); 47 } 48 } 49 50 51 //output: 52 /**Analyzing begin: 53 Interfaces: 54 Base:class java.lang.Enum 55 Methods: 56 [compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, values, wait] 57 Analyzing begin: 58 Interfaces: 59 java.lang.Comparable<E>interface java.io.SerializableBase:class java.lang.Object 60 Methods: 61 [compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, wait] 62 Explore containsAll(Enum)?true 63 Explore removeAll(Enum)true 64 [values] 65 */
反编译之前的枚举类型Gender
javac Gender.class
javap Gender
Compiled from "Gender.java"
public final class com.Gender extends java.lang.Enum<com.Gender> {
public static final com.Gender MALE;
public static final com.Gender FEMALE;
public static com.Gender[] values();
public static com.Gender valueOf(java.lang.String);
static {};
}
values()是由编译器添加的static方法。编译器还添加了valueOf()方法。
添加的这个valueOf()方法和Enum中的valueOf()方法不同。前者只有一个参数而后者有两个。
由于values()方法是由编译器插入到enum定义的static方法,当enum实例向上转型为Enum,values()方法就不能调用了。
Class中有个getEnumConstants()方法可以获取到所有enum实例。
1 package com; 2 3 /** 4 * Created by JohnTsai on 15/10/25. 5 */ 6 public class UpcastEnum { 7 public static void main(String[] args) { 8 Gender[] values = Gender.values(); 9 Enum e = Gender.MALE; 10 // e.values();No values() in Enum 11 for (Enum en : e.getClass().getEnumConstants()) { 12 System.out.println(en); 13 } 14 } 15 } 16 17 //output 18 /** 19 MALE 20 FEMALE 21 */
实现,而非继承
所有的enum都继承自java.lang.Enum类。
1 System.out.println("Gender's super class:"+Gender.class.getSuperclass()); 2 //output: 3 //Gender's super class:class java.lang.Enum
由于java不支持多继承,所以enum不能再继承其他类了。然而,我们可以在创建一个新的enum时,可以同时实现一个或多个接口。
转载:http://www.cnblogs.com/JohnTsai/p/4903125.html