Java的枚举类型

引用并转载于:http://blog.csdn.net/ishallwin/article/details/9440251

1.什么是枚举:

          在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的。

     例如:星期一到星期日七个数据元素组成了一周的“数据集”,春夏秋冬四个数据元素组成了四季的“数据集”。

     在java中如何更好的使用这些“数据集”呢?因此枚举便派上了用场。

          枚举是限定有限可能值的一种手段,使用枚举可以降低程序出错的几率,并可以提高代码的可读性与可维护性

     Java中的枚举并不是简单常量的集合,而是一个对象,其本质依然是类,

     所以Java中的枚举除了提供一系列相关值以外,还提供了一些额外功能,甚至还可以根据需要自行添加一些功能。

2. 常规用法

      尽管Java中的枚举是对象,但是大多数使用它的场景与其它语言中并无二致。

     2.1 定义

           定义枚举需要使用关键字enum。例如一个应用需要使用一系列特定的颜色值,则可以定义一个类似以下形式的枚举。

           这里是直接定义了一个MyColor.java的文件,文件的内容如下:  

1 //这里不用写class关键字,因为只要有enum这个类就会自动继承
2 //java.lang.Enum类
3 public enum MyColor{
4    //每个枚举值用逗号隔开,
5    RED,
6    BLUE,
7    GREEN;//最后的分号可要或不要
8 }
View Code

          可以看到enum真是一个对象,因为生成了MyColor.class文件:

          

     2.2.  使用

          枚举定义完成以后,就可以以“枚举名.枚举项”的形式在代码中对定义的枚举进行使用。

          在特殊情况下,如果程序能够识别出当前的枚举类型,则只需要给出枚举项即可,

         例如:

             在switch语句块中的case关键字后的常量值。

 1 public class Test1{
 2     public static void main(String[] args){
 3         // MyColor myColor = new MyColor();
 4         //这里不能直接实例化它,尽管MyColor实质是一个类
 5         //后面会有详细解释,因为它的构造方法默认是私有的
 6         MyColor myColor = MyColor.RED;
 7         switch(myColor){
 8             case BLUE://这里就可以直接使用枚举值
 9                 System.out.println("蓝色");
10                 break;
11             case GREEN:
12                 System.out.println("绿色");
13                 break;
14             case RED:
15                 System.out.println("红色");
16                 break;
17             default:
18                 System.out.println("什么色?");
19                 break;    
20         }
21     }
22 }
View Code  

            

3. Enum类型的常用方法

            Java枚举提供了几个方法供开发者在需要时调用,

      对于枚举对象,主要可用的方法为values(),它返回当前枚举中定义的所有枚举项的集合;

      对于枚举项,主要可用的方法有3个方法ordinal()name()getDeclaringClass()

           方法ordinal()返回枚举项在枚举对象中的序号,从0开始;

           方法name()则返回枚举项的名称(与方法toString效果相同),通常用于取得枚举变量中保存的枚举项名称;

           方法getDeclaringClass()则用于取得当前枚举值所在类的完整名称。

           此外,枚举项之间还可以通过方法compareTo()进行比较,如果参数传入的枚举项与当前值相等,则返回0

     测试代码:

 1 public class Test{
 2     public enum MyColor{
 3         RED,
 4         BLUE,
 5         GREEN;
 6     }
 7 
 8     public static void main(String[] args){
 9         for(MyColor myColor: MyColor.values()){
10             System.out.println(myColor);
11             System.out.println(myColor.ordinal());
12             System.out.println(myColor.name());
13             System.out.println(myColor.getDeclaringClass());  
14             System.out.println("============================================");
15         }
16     }        
17 
18 }
View Code

      其运行结果如图 :

                     

      通过javac编译后可以看到,enum的确是作为类而存在,因为编译后生成了2个class文件   

          

4. 为枚举添加构造器和成员方法

       4.1.构造器

             类拥有构造器,枚举是一种特殊的类,所以枚举也可以拥有自己的构造器。

             但与普通类的不同之处在于枚举的构造器不可以是public,其原因在于该构造器是提供给枚举对象中的枚举项构造时使用的,它并不需要在枚举对象之外使用。

 

             例如,如果希望枚举MyColor中的每个枚举项包含有相应的中文说明以及其对应的Color信息,

                     则可以为MyColor增加一个包含有两个参数的构造器,并且在声明每一个枚举项时使用这个构造器进行构造。其实现代码如下:

 1 import java.awt.Color;
 2 public enum MyColor{
 3     /*
 4      *关于枚举类型的构造方法,只需要记住两点
 5      *1.枚举类型的构造方法是被枚举项使用的,而不是被外部使用的
 6     */
 7     RED("红色",Color.RED),
 8     BLUE("蓝色",Color.BLUE),
 9     GREEN("绿色",Color.GREEN);
10     
11     private String description;
12     private Color color;
13     
14     /*
15      *2.枚举类型的构造方法是私有的private,这就很好的说明了第一点
16      *  所以枚举的使用是不能通过new来使用的,
17      *  而是使用 枚举类型.枚举项
18      **/
19     private MyColor(String desc,Color color){
20         this.description = desc;
21         this.color = color;
22     }
23     
24     public static void main(String[] args){
25         for(MyColor mc:MyColor.values()){
26             System.out.println(mc.description);
27             System.out.println(mc.color.toString());
28         }
29     }
30 }
View Code

              结果如图:

              

     

      4.2.  成员方法

           如同可以为枚举添加构造器(构造方法)一样也可以为枚举类型添加方法。

          例如上述代码中,通过构造器为每个枚举项添加了中文说明以及其对应的Color信息,

                 那么为了取出枚举项对应的信息,则需要为枚举MyColor添加如下相应方法。

1     //返回当前描述
2     public String getDescription() {
3            return this.description;
4     }
5 
6    //返回对应的颜色
7     public Color getColor(){
8           return this.color;
9      }
View Code

       

         可以看到,通过以上机制,可以将枚举本身要表达的含义与其具体的信息很好地整合起来,杜绝了传统编程语言中含义与信息分离的弊端。

 

5、枚举集合

             Java中的枚举是一个对象,枚举对象中的各枚举项也是对象。

      在Java中,集合容器要求存储在其中的每一个成员均是对象类型,而枚举作为一种特殊的类,

      Java亦专门为枚举提供了集合容器EnumSetEnumMap

      5.1. EnumSet

             EnumSet用于保存枚举项的集合,在枚举项本身并不互斥的情况下特别有用。

      例如,一个应用系统通常会有多种角色,而某些人在系统中可能承担不止一种角色。如果这些角色是通过枚举定义的,则此时EnumSet将可以将多种角色保存在一起,标识特定用户承担的全部角色。

             EnumSet扩展于AbstractSet它除了拥了普通Set所拥有的方法外,主要是增加了一系列可产生EnumSet实例的方法(noneOf、allOf、copyOf、complementOf、of、range等)。

             以下是使用EnumSet的of方法产生一个EnumSet实例的示例。

 1 import java.util.EnumSet;
 2 public class EnumSetTest{
 3     public enum Role{
 4         ROOT,TEST,CUSTOMER
 5     }
 6 
 7 
 8     public static void main(String[] args){
 9         //EnumSet.of()是往里面添加元素
10         EnumSet<Role> es = EnumSet.of(Role.ROOT,Role.TEST);
11         for(Role r:es){
12             System.out.println(r);
13         }
14     }
15 }
View Code

         更多EnumSet的方法,请参考:http://tool.oschina.net/apidocs/apidoc?api=jdk_7u4

 

          5.2. EnumMap

                 EnumMap是必须使用枚举项作为其KEY的Map,其法与普通Map类似。

                 更多EnumMap请参考:http://tool.oschina.net/apidocs/apidoc?api=jdk_7u4

            

posted @ 2015-02-08 23:04  一菲聪天  阅读(951)  评论(0编辑  收藏  举报