Java枚举
学习Java枚举
今天将要系统的学习一下java中的枚举,以便在以后开发的道路上能够更熟练的使用枚举类型。
关键字enum可以将一组具名的值的有限集合创建为一种新的类型。而这些具名的值可以作为常规的程序组件使用。这是一种非常有用的功能。
1. 基本enum的特性
1.1 创建enum
用enum关键字声明枚举(类似声明类的class),
创建enum时,编译器会为你生成一个相关的类,该类继承自java.long.Enum。
1 enum Shrubbery { 2 GROUND, 3 CRAWLING, 4 HANGING, 5 }
1.2 values()方法
enum的values()方法可以遍历enum的实例。values()方法返回enum实例的数组,数组中的元素顺序就是,在enum中声明时的顺序。
1 for (Shrubbery shrubbery : Shrubbery.values()) { 2 System.out.println(shrubbery + "ordinal: " + shrubbery.ordinal()); 3 }
结果:
1 GROUND ordinal: 0 2 CRAWLING ordinal: 1 3 HANGING ordinal: 2
1.3 ordinal()方法
ordinan()方法返回一个int值,该值就是enum在声明时的次序。从0开始。
1.4 enum实例的比较
Enum类实现了Comparable接口和Serializable接口。
1.5 Enum.valueOf(Class<T> enumType,String name),将字符串转化为指定类型的枚举
1 for (String s : "GROUND CRAWLING HANGING".split(" ")) { 2 Shrubbery shrubbery = Enum.valueOf(Shrubbery.class, s); 3 System.out.println(shrubbery); 4 }
结果:
1 GROUND 2 CRAWLING 3 HANGING
1.6 name()方法
name()方法返回enum实例声明时的名字,和toString()方法效果一样。
2. 向enum中添加新方法
除了enum之间不能继承之外,我们可以把enum看成一个class类,可以向enum中添加方法,甚至可以加main方法。
1 package com.guolele.durian.util; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 /** 7 * Created by luotong on 2016/6/6. 8 */ 9 public enum XinQi { 10 MONDAY(1,"周一"), 11 TUESDA(2,"周二"), 12 WEDNESDAY(3,"周三"), 13 THURSDAY(4,"周四"), 14 FRIDAY(5,"周五"), 15 SATURDAY(6,"周六"), 16 SUNDAY(7,"周日"); 17 18 //成员变量 19 private int index; 20 private String desc; 21 22 private static final Map<Integer,String> map = new HashMap<>(); 23 24 static { 25 for (XinQi xinQi : XinQi.values()) { 26 map.put(xinQi.index,xinQi.desc); 27 } 28 } 29 //构造方法 30 XinQi(int index, String desc) { 31 this.index = index; 32 this.desc = desc; 33 } 34 //普通方法 35 public static String getDescByIndex(Integer index){ 36 for (XinQi xinQi : XinQi.values()) { 37 if (xinQi.index == index) { 38 return xinQi.desc; 39 } 40 } 41 return null; 42 } 43 //set get 方法 44 public int getIndex() {return index;} 45 46 public void setIndex(int index) {this.index = index;} 47 48 public String getDesc() {return desc;} 49 50 public void setDesc(String desc) {this.desc = desc;} 51 }
2.1 enum中定义属性,构造方法,set、get方法,main方法
1 package enumstudy; 2 3 /** 4 * Created by luotong on 2016/6/4. 5 * <p> 6 * 枚举中定义属性,构造方法,main函数,set,get方法 7 * </p> 8 */ 9 public enum OzWitch { 10 WEST("Miss Gulch, aka ..."), 11 NORTH("Glinda,thGood ..."), 12 EAST("Wicked Witch of ..."), 13 SOUTH("Good by ..."); 14 15 private String describtion; 16 17 OzWitch(String describtion) { 18 this.describtion = describtion; 19 } 20 21 public String getDescribtion() {return describtion;} 22 23 public void setDescribtion(String describtion) {this.describtion = describtion; } 24 25 public static void main(String[] args) { 26 for (OzWitch o : OzWitch.values()) { 27 System.out.println(o.getDeclaringClass() + " " + o.name() + " ordinal: " + o.ordinal() + " " + o.getDescribtion()); 28 } 29 } 30 }
结果:
class enumstudy.OzWitch WEST ordinal: 0 Miss Gulch, aka ... class enumstudy.OzWitch NORTH ordinal: 1 Glinda,thGood ... class enumstudy.OzWitch EAST ordinal: 2 Wicked Witch of ... class enumstudy.OzWitch SOUTH ordinal: 3 Good by ...
备注:
(1)如果要在enum中定义方法,必须在enum中定义的实例最后加上分号,同时Java要求你必须先定义实例,如果在定义实例之前定义了方法或者属性,编译器会报错。
(2)我们只能在enum定义的内部使用其构造器来创建实例。enum定义结束,编译器就不允许我们利用构造器来定义人和的实例了。
2.2 覆盖enum的方法
重写toString()方法。
1 package enumstudy; 2 3 /** 4 * Created by luotong on 2016/6/4. 5 */ 6 public enum SpaceShip { 7 SCOUT,CARGO,TRANSPORT,CRUISER,BATTLESHIP; 8 9 @Override 10 public String toString() { 11 String name = name(); 12 String lower = name.substring(1).toLowerCase(); 13 return name.charAt(0)+lower; 14 } 15 16 public static void main(String[] args) { 17 for (SpaceShip spaceShip : SpaceShip.values()) { 18 System.out.println(spaceShip.toString()); 19 } 20 } 21 }
3. switch语句中的enum
在switch语句中使用enum,是enum提供的非常便利的功能。
1 package enumstudy; 2 3 /** 4 * Created by luotong on 2016/6/4. 5 * <p>switch语句中使用enum</p> 6 */ 7 8 enum Signal{ 9 GREEN,RED,YELLOW 10 } 11 12 public class TrafficLight { 13 Signal color = Signal.RED; 14 15 public void change(){ 16 switch (color) { 17 case RED : color = Signal.GREEN; 18 break; 19 case GREEN: color = Signal.YELLOW; 20 break; 21 case YELLOW: color = Signal.RED; 22 break; 23 } 24 } 25 26 @Override 27 public String toString() { 28 return "The Traffic Light is " + color; 29 } 30 31 public static void main(String[] args) { 32 TrafficLight trafficLight = new TrafficLight(); 33 for (int i = 0 ;i< 7;i++){ 34 System.out.println(trafficLight); 35 trafficLight.change(); 36 } 37 } 38 }
4.values()的神秘之处
自定义的enum中的values()方法是有编译器添加的static方法,Enum类中并没有values()方法。
自定义的enum是由final修饰的,所以自定义的enum不能被继承。
1 package enumstudy; 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 luotong on 2016/6/4. 10 * 11 * <p> 12 * values()的神秘之处: 13 * values方法,是在编译器变异的时候生成的static方法。 14 * <p/> 15 */ 16 17 enum Explore { 18 HERE,THERE 19 } 20 21 public class Reflection { 22 public static Set<String> analyze(Class<?> enumClass){ 23 System.out.println("--------analyze enum------return methods--------"); 24 25 System.out.println("interface: "); 26 for (Type type : enumClass.getGenericInterfaces()) { 27 System.out.println(type); 28 } 29 30 System.out.println("base : " + enumClass.getSuperclass()); 31 32 Set<String> methods = new TreeSet<String>(); 33 for (Method method : enumClass.getMethods()) { 34 methods.add(method.getName()); 35 } 36 System.out.println(methods); 37 return methods; 38 } 39 40 public static void main(String[] args) { 41 Set<String> exploreMethods = analyze(Explore.class); 42 Set<String> enumMethods = analyze(Enum.class); 43 44 if (exploreMethods.containsAll(enumMethods)) { 45 System.out.println("Explore 中包含Enum中所有的方法"); 46 } 47 48 exploreMethods.removeAll(enumMethods); 49 50 System.out.println(exploreMethods); 51 52 /** 53 * 自定义的enum向上转型为Enum时没有values方法,但可以通过 54 * Class对象的getEnumConstants方法获得enum的实例 55 */ 56 Enum ex = Explore.HERE; 57 for (Enum anEnum : ex.getClass().getEnumConstants()) { 58 System.out.println(anEnum.name()); 59 } 60 } 61 62 }
结果:
--------analyze enum------return methods-------- interface: base : class java.lang.Enum [compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, values, wait] --------analyze enum------return methods-------- interface: java.lang.Comparable<E> interface java.io.Serializable base : class java.lang.Object [compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, wait] Explore 中包含Enum中所有的方法 [values] HERE THERE