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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2016-06-04 10:55  铜锣  阅读(197)  评论(0编辑  收藏  举报