Java枚举总结

 

 

声明:本文仅仅是总结学习笔记,使用了以下3篇文章

1.      java枚举

(http://cardyn.iteye.com/blog/904534)

2.      详细介绍java中的枚举类型

(http://developer.51cto.com/art/201107/275031.htm)

3.      Java 枚举7常见种用法

(http://www.iteye.com/topic/1116193)

 

一.  Thinking in Java 定义:

关键字ENUM 可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用。

 

二.  使用枚举的意义:

枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。

 

三.  没有枚举类型的时候

采用A. 私有构造函数B. 每个元素用公有的静态成员变量表示并且调用私有构造函数,来模拟枚举类型

/**
  * 颜色类
  */
classColor{
/**
        * 每个元素用公有的静态成员变量表示
        */
//红色
        public  static finalColor RED =newColor();
//蓝色
        public  static finalColor BLUE   =newColor();
//黑色
        public  static finalColor BLACK =newColor();
/**
         * 私有的构造函数
        * 防止外部创建该对象
        */
        privateColor(){}
}
 
四.枚举类型的详细介绍
 
/**
 * 颜色枚举
 */
enumColor {  
       RED, BLUE,BLACK, YELLOW,GREEN; 
}

 

        显然,enum很像特殊的class,实际上enum声明定义的类型就是一个类。而这些类都是类库中Enum类的子类(java.lang.Enum)。它们继承了这个Enum中的许多有用的方法。我们对代码编译之后发现,编译器将enum类型单独编译成了一个字节码文件:Color.class。

 

final  enumhr.test.Color {  
// 所有的枚举值都是类静态常量 
public  static final  enumhr.test.Color RED;  
public  static final  enumhr.test.Color BLUE;  
public  static final  enumhr.test.Color BLACK;  
public  static final  enumhr.test.Color YELLOW;  
public  static final  enum hr.test.ColorGREEN;  
private  static finalsynthetic hr.test.Color[] ENUM$VALUES; 
// 初始化过程,对枚举类的所有枚举值对象进行第一次初始化 
static{  
    0 newhr.test.Color [1] 
    3 dup 
//把枚举值字符串“RED”压入操作数栈 
    4 ldc [16]
// 把整型值0压入操作数栈 
    6 iconst_0
//调用Color类的私有构造器创建Color对象RED 
    7 invokespecial hr.test.Color(java.lang.String, int) [17]
//将枚举对象赋给Color的静态常量RED。 
    10 putstatic hr.test.Color.RED : hr.test.Color [21]
//枚举对象BLUE等与上同 
    102 return
};  
// 私有构造器,外部不可能动态创建一个枚举类对象(也就是不可能动态创建一个枚举值)。 
privateColor(java.lang.String arg0,int arg1){  
// 调用父类Enum的受保护构造器创建一个枚举对象 
    3 invokespecial java.lang.Enum(java.lang.String, int) [38] 
    };  
    public  statichr.test.Color[] values();  
// 实现Enum类的抽象方法 
    public  statichr.test.Color valueOf(java.lang.String arg0);  
}

 

下面我们就详细介绍enum定义的枚举类的特征及其用法。(后面均用Color举例)

 

A.  Color枚举类就是class,而且是一个不可以被继承的final类

其枚举值(RED,BLUE.。.)都是Color类型的类静态常量, 我们可以通过下面的方式来得到Color枚举类的一个实例:

//获得一个枚举值

       Colorc = Color.RED;

      

           注意:这些枚举值都是public static final的,也就是我们经常所定义的常量方式,因此枚举类中的枚举值最好全部大写。

 

B.  即然枚举类是class,当然在枚举类型中有构造器,方法和数据域

但是,枚举类的构造器有很大的不同:

 

1.  构造器只是在构造枚举值的时候被调用

 

/**
 * 颜色枚举
 */
enumColor {
  
  RED(255,0, 0), 
  BLUE(0,0, 255), 
  BLACK(0,0, 0), 
  YELLOW(255,255, 0),
  GREEN(0,255, 0);
  
// 构造枚举值,比如RED(255,0,0)
  privateColor(int rv,int gv, int bv){
     this.redValue
     this.greenValue
     this.blueValue
  }
// 覆盖了父类Enum的toString()
  publicString toString() {
     return   "(" + redValue +  ","
greenValue +  ","
blueValue +  ")";
  }
// 自定义数据域,private为了封装。
  private  int redValue; 
  private  int greenValue;
  private  int blueValue;
}

 

2.构造器只能私有private,绝对不允许有public构造器。 这样可以保证外部代码无法新构造枚举类的实例。这也是完全符合情理的,因为我们知道枚举值是public static final的常量而已。 但枚举类的方法和数据域可以允许外部访问

 

public  static voidmain(String[] args) {
//编译错误,外部不可以实例化Color
//Colorcolors=new Color(100,200,300);
//获得一个枚举值
     Color c = Color.RED;
//调用了toString()方法 输出 (255,0,0)
     System.out.println(c);
}

 

3.所有枚举类都继承了Enum的方法,下面我们详细介绍这些方法

 

l  ordinal()

返回枚举值在枚举类种的顺序。这个顺序根据枚举值声明的顺序而定

 

Color.RED.ordinal();  //返回结果:0 

Color.BLUE.ordinal();//返回结果:1

 

l  compareTo()

Enum实现了java.lang.Comparable接口,因此可以比较象与指定对象的顺序。Enum中的compareTo返回的是两个枚举值的顺序之差。当然,前提是两个枚举值必须属于同一个枚举类,否则会抛出ClassCastException()异常。(具体可见源代码)

             

              Color.RED.compareTo(Color.BLUE);//返回结果 -1

             

l  values()

静态方法,返回一个包含全部枚举值的数组

 

//获得包含全部枚举值的数组
       Color[]  colors=Color.values();  
//遍历输出
       for(Color color : colors) {
         System.out.print(color.name()+"" +  color + "-");
       }
//结果:RED(255,0,0)-BLUE(0,0,255)-BLACK(0,0,0)-YELLOW(255,255,0)-GREEN(0,255,0)
 
l  toString()
返回枚举常量的名称
Color c = Color.RED;  
System.out.println(c);//返回结果: RED

l  valueOf()

这个方法和toString方法是相对应的,返回带指定名称的指定枚举类型的枚举常量

//返回结果: Color.BLUE
              Colorblue = Color.valueOf("BLUE");
//(0,0,255)
System.out.println(blue);
 
l  equals()
比较两个枚举类对象的引用
 
//JDK源代码: 
public  final booleanequals(Object other) { 
       return  this==other;  
}

 

五.Java 枚举7常见种用法

 

1.常量

在JDK1.5 之前,我们定义常量都是: public static fianl ....。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法

/**
 * 颜色枚举
 */
enum Color { 
     RED, BLUE,BLACK, YELLOW,GREEN; 
}
 
2.switch
 
//获得红色枚举
    Colorcolor = Color.RED;
//使用判断
    switch(color) {
    case RED:
     System.out.println("it‘s red");
    break;
    case BLUE:
     System.out.println("it’s blue");
    break;
    case BLACK:
     System.out.println("it‘s blue");
    break;
    }
//结果:it‘s red

 

3.向枚举中添加新方法

如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例

 

enumColor {
     RED("红色", 1),GREEN("绿色", 2),BLANK("白色", 3),YELLO("黄色", 4);
// 成员变量
     privateStringname;
     private  int index;
 
// 构造方法
     privateColor(String name,intindex) {
         
         this.index
     }
 
/**
      * 用户自定义方法
      * 获得颜色名称
      */
     public  staticString getName(intindex) {
         for(Color c : Color.values()) {
            if(c.getIndex() == index) {
                return ;
            }
         }
         return  null;
     }
 
// get set 方法
     publicString getName() {
         returnname;
     }
     public  voidsetName(String name) {
         
     }
     public  intgetIndex() {
         returnindex;
     }
     public  voidsetIndex(intindex) {
         this.index
     }
  }
  
  public  static voidmain(String[] args) {
//获得红色枚举
     Color color = Color.RED;
//红色
     System.out.println(color.getName(color.getIndex()));
}

 

4.覆盖枚举的方法

上面示例已经有了

 

5.    实现接口

/**
 * 行为接口
 */
interfaceBehaviour {
/**
   * 输出
   */
  voidprint();
/**
   * 获得信息
   */
  String getInfo();
}
  enum Color implements  Behaviour {
       RED("红色", 1),GREEN("绿色", 2),BLANK("白色", 3),YELLO("黄色", 4);
// 成员变量
       privateStringname;
       private  int index;
 
// 构造方法
       privateColor(String name,intindex) {
           
           this.index
       }
 
/**
        * 接口方法:输出
        */
@Override
       public  voidprint() {
           System.out.println(this.index+":"+);
           
       }
/**
        * 接口方法:获得信息
        */
@Override
       publicString getInfo() {
           return  ;  
       }
       
// get set 方法
       publicString getName() {
           returnname;
       }
       public  voidsetName(String name) {
           
       }
       public  intgetIndex() {
           returnindex;
       }
       public  voidsetIndex(intindex) {
           this.index
       }
    }
    
    public  static voidmain(String[] args) {
//获得红色枚举
       Color color = Color.RED;
//1:红色
       color.print();
//红色
       System.out.println(color.getInfo());
       
    }
        
6.使用接口组织枚举
 
/**
 * 食物接口
 */
public  interface Food{
/**
   * 咖啡枚举
   */
  enumCoffee implements Food{
     BLACK_COFFEE, DECAF_COFFEE, LATTE,CAPPUCCINO
  }
  
/**
   * 甜点枚举
   */
  enumDessertimplements Food{
     FRUIT, CAKE,GELATO
  }
}

 

7.关于枚举集合的使用

java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的 key是enum类型,而value则可以是任意类型

     

//初始化EnumSet
       EnumSet<Color>colorSet = EnumSet.allOf(Color.class);
//遍历输出
       for(Color temp : colorSet) {
           System.out.print(temp+"-");
       }
//结果:RED-GREEN-BLANK-YELLO
       
//初始化EnumMap
       EnumMap<Color,String> colorMap = newEnumMap<Color, String>(Color.class);
//赋值
       colorMap.put(Color.RED,"我是红色");
       colorMap.put(Color.BLANK,"我是蓝色");
//遍历输出
       for(Color key : colorMap.keySet()) {
           System.out.println(colorMap.get(key));
       }
//结果:我是红色/我是蓝色