Enum 枚举详解

以前也是一直认为枚举的用处不太(相信不止我一个人认为),潜意识里根本不会想去用它,最近看了几篇文章才发现枚举也是非常的有用。


现在我把我看到的也转来让大家看看


其一:http://blog.sina.com.cn/s/blog_4adc4b090101dtxp.html


枚举是一种规范它规范了参数的形式,这样就可以不用考虑类型的不匹配并且显式的替代了int型参数可能带来的模糊概念 枚举像一个类,又像一个数组。


Enum作为Sun全新引进的一个关键字,看起来很象是特殊的class, 它也可以有自己的变量,可以定义自己的方法,可以实现一个或者多个接口。 当我们在声明一个enum类型时,我们应该注意到enum类型有如下的一些特征。 


1.它不能有public的构造函数,这样做可以保证客户代码没有办法新建一个enum的实例。 


2.所有枚举值都是public , static , final的。注意这一点只是针对于枚举值,我们可以和在普通类里面定义 变量一样定义其它任何类型的非枚举变量,这些变量可以用任何你想用的修饰符。 


3.Enum默认实现了java.lang.Comparable接口。 


4.Enum覆载了了toString方法,因此我们如果调用Color.Blue.toString()默认返回字符串”Blue”. 


5.Enum提供了一个valueOf方法,这个方法和toString方法是相对应的。调用valueOf(“Blue”)将返回Color.Blue.因此我们在自己重写toString方法的时候就要注意到这一点,一把来说应该相对应地重写valueOf方法。 


6.Enum还提供了values方法,这个方法使你能够方便的遍历所有的枚举值。 


7.Enum还有一个oridinal的方法,这个方法返回枚举值在枚举类种的顺序,这个顺序根据枚举值声明的顺序而定,这里Color.Red.ordinal()返回0。 


了解了这些基本特性,我们来看看如何使用它们。 


1.遍历所有有枚举值. 知道了有values方法,我们可以轻车熟路地用ForEach循环来遍历了枚举值了。 


for (Color c: Color.values()) 
System.out.println(“find value:” + c); 


2.在enum中定义方法和变量,比如我们可以为Color增加一个方法随机返回一个颜色。 


public enum Color { 
Red, 
Green, 
Blue; 




private static int number = Color.values().length ; 




public static Color getRandomColor(){ 
long random = System.currentTimeMillis() % number; 
switch ((int) random){ 
case 0: 
return Color.Red; 
case 1: 
return Color.Green; 
case 2: 
return Color.Blue; 
default : return Color.Red; 





可以看出这在枚举类型里定义变量和方法和在普通类里面定义方法和变量没有什么区别。唯一要注意的只是变量和方法定义必须放在所有枚举值定义的后面,否则编译器会给出一个错误。 


3.覆载(Override)toString, valueOf方法 


前面我们已经知道enum提供了toString,valueOf等方法,很多时候我们都需要覆载默认的toString方法,那么对于enum我们怎么做呢。其实这和覆载一个普通class的toString方法没有什么区别。 


…. 
public String toString(){ 
switch (this){ 
case Red: 
return "Color.Red"; 
case Green: 
return "Color.Green"; 
case Blue: 
return "Color.Blue"; 
default: 
return "Unknow Color"; 


…. 


这时我们可以看到,此时再用前面的遍历代码打印出来的是 


Color.Red 
Color.Green 
Color.Blue 


而不是 


Red 
Green 
Blue. 


可以看到toString确实是被覆载了。一般来说在覆载toString的时候我们同时也应该覆载valueOf方法,以保持它们相互的一致性。 


4.使用构造函数 


虽然enum不可以有public的构造函数,但是我们还是可以定义private的构造函数,在enum内部使用。还是用Color这个例子。 


public enum Color { 
Red("This is Red"), 
Green("This is Green"), 
Blue("This is Blue"); 


private String desc; 


Color(String desc){ 
this.desc = desc; 



public String getDesc(){ 
return this.desc; 






这里我们为每一个颜色提供了一个说明信息, 然后定义了一个构造函数接受这个说明信息。 


要注意这里构造函数不能为public或者protected, 从而保证构造函数只能在内部使用,客户代码不能new一个枚举值的实例出来。这也是完全符合情理的,因为我们知道枚举值是public static final的常量而已。 


5.实现特定的接口 


我们已经知道enum可以定义变量和方法,它要实现一个接口也和普通class实现一个接口一样,这里就不作示例了。 


6.定义枚举值自己的方法。 


前面我们看到可以为enum定义一些方法,其实我们甚至可以为每一个枚举值定义方法。这样,我们前面覆载 toString的例子可以被改写成这样。 


public enum Color { 
Red { 
public String toString(){ 
return "Color.Red"; 

}, 
Green { 
public String toString(){ 
return "Color.Green"; 

}, 
Blue{ 
public String toString(){ 
return "Color.Blue"; 

}; 



从逻辑上来说这样比原先提供一个“全局“的toString方法要清晰一些。 


总的来说,enum作为一个全新定义的类型,是希望能够帮助程序员写出的代码更加简单易懂,个


人觉得一般也不需要过多的使用enum的一些高级特性,否则就和简单易懂的初衷想违背了。




其二: http://weilingfeng98.iteye.com/blog/860010

java的Enum枚举类型终于在j2se1.5出现了。之前觉得它只不过是鸡肋而已,可有可无。毕竟这么多年来,没有它,大家不都过得很好吗?今日看《Thinking in Java》4th edition,里面有一句话“有时恰恰因为它,你才能够"优雅而干净"地解决问题。优雅与清晰很重要,正式它们区别了成功的解决方案与失败的解决方案。而失败的解决方案就是因为其他人无法理他。"使用Enum枚举类型,可以将以前笨拙的代码变得优雅简单?但是,我同时也在思考另外一个问题,使用新的技术,会不会给技术人员带来更多的负担呢? 

"学习新版语言的一个危险就是疯狂使用新的语法结构" 

先学习一下enum的简单应用,以下简洁的代码已经包括enum所提供的绝大部分功能。 

1.enum的应用,包括定义,遍历,switch,enumset,enummap等 

Java代码 
package com.janeky.enumtest;    
import java.util.EnumMap;    
import java.util.EnumSet;    
   
/**   
* Java枚举类型enum使用详解   
* @version 2009/9/5   
* @author janeky   
* @mail rojaneky@gmail.com   
*   
*/   
public class EnumTest {    
   
    //定义一个enum枚举类型,包括两个实例ON,OFF    
    public enum State {    
        ON, OFF    
    };    
   
    //测试函数    
    public static void main(String[] args) {    
        //直接变量enum    
        for (State s : State.values())    
            System.out.println(s.name());    
   
        //switch与enum的结合使用    
        State switchState = State.OFF;    
        switch (switchState) {    
        case OFF:    
            System.out.println("OFF");    
            break;    
        case ON:    
            System.out.println("ON");    
            break;    
        }    
   
        //EnumSet的使用    
        EnumSet stateSet = EnumSet.allOf(State.class);    
        for (State s : stateSet) {    
            System.out.println(s);    
        }    
   
        //EnumMap的使用    
        EnumMap stateMap = new EnumMap(    
                State.class);    
        stateMap.put(State.ON, "is On");    
        stateMap.put(State.OFF, "is off");    
        for (State s : State.values()) {    
            System.out.println(s.name() + ":" + stateMap.get(s));    
        }    
    }    
   
}   
package com.janeky.enumtest; 
import java.util.EnumMap; 
import java.util.EnumSet; 

/** 
* Java枚举类型enum使用详解 
* @version 2009/9/5 
* @author janeky 
* @mail rojaneky@gmail.com 

*/ 
public class EnumTest { 

//定义一个enum枚举类型,包括两个实例ON,OFF 
public enum State { 
  ON, OFF 
}; 

//测试函数 
public static void main(String[] args) { 
  //直接变量enum 
  for (State s : State.values()) 
   System.out.println(s.name()); 

  //switch与enum的结合使用 
  State switchState = State.OFF; 
  switch (switchState) { 
  case OFF: 
   System.out.println("OFF"); 
   break; 
  case ON: 
   System.out.println("ON"); 
   break; 
  } 

  //EnumSet的使用 
  EnumSet stateSet = EnumSet.allOf(State.class); 
  for (State s : stateSet) { 
   System.out.println(s); 
  } 

  //EnumMap的使用 
  EnumMap stateMap = new EnumMap( 
    State.class); 
  stateMap.put(State.ON, "is On"); 
  stateMap.put(State.OFF, "is off"); 
  for (State s : State.values()) { 
   System.out.println(s.name() + ":" + stateMap.get(s)); 
  } 





为每个enum实例定义不同的方法 

Java代码 
package com.janeky.enumtest;    
   
public enum TestEnumMathod {    
    //为每个enum实例添加不同的实现方法    
    SAMPLE1 {    
        String getInfo() {    
            return "SAMPLE1";    
        }    
    },    
    SAMPLE2{    
        String getInfo()    
        {    
            return "SAMPLE2";    
        }    
    };    
    abstract String getInfo();    
        
    //测试    
    public static void main(String args[])    
    {    
        for(TestEnumMathod method:values())    
        {    
            System.out.println(method.getInfo());    
        }    
    }    
        
}   
package com.janeky.enumtest; 

public enum TestEnumMathod { 
//为每个enum实例添加不同的实现方法 
SAMPLE1 { 
  String getInfo() { 
   return "SAMPLE1"; 
  } 
}, 
SAMPLE2{ 
  String getInfo() 
  { 
   return "SAMPLE2"; 
  } 
}; 
abstract String getInfo(); 

//测试 
public static void main(String args[]) 

  for(TestEnumMathod method:values()) 
  { 
   System.out.println(method.getInfo()); 
  } 



以下内容可能有些无聊,但绝对值得一窥 
1. 
public class State { 
  public static final int ON = 1; 
  public static final Int OFF= 0; 


有什么不好了,大家都这样用了很长时间了,没什么问题啊。 
首先,它不是类型安全的。你必须确保是int 
其次,你还要确保它的范围是0和1 
最后,很多时候你打印出来的时候,你只看到 1 和0 , 

但其没有看到代码的人并不知道你的企图 
so,抛弃你所有旧的public static final常量吧 

2.可以创建一个enum类,把它看做一个普通的类。除了它不能继承其他类了。(java是单继承,它已经继承了Enum), 
可以添加其他方法,覆盖它本身的方法 

3.switch()参数可以使用enum了 

4.values()方法是编译器插入到enum定义中的static方法,所以,当你将enum实例向上转型为父类Enum是,values()就不可访问了。解决办法:在Class中有一个getEnumConstants()方法,所以即便Enum接口中没有values()方法,我们仍然可以通过Class对象取得所有的enum实例 

5.无法从enum继承子类,如果需要扩展enum中的元素,在一个接口的内部,创建实现该接口的枚举,以此将元素进行分组。达到将枚举元素进行分组。 

6.使用EnumSet代替标志。enum要求其成员都是唯一的,但是enum中不能删除添加元素。 

7.EnumMap的key是enum,value是任何其他Object对象。 

8.enum允许程序员为eunm实例编写方法。所以可以为每个enum实例赋予各自不同的行为。 

9.使用enum的职责链(Chain of Responsibility) .这个关系到设计模式的职责链模式。以多种不同的方法来解决一个问题。然后将他们链接在一起。当一个请求到来时,遍历这个链,直到链中的某个解决方案能够处理该请求。 

10.使用enum的状态机 

11.使用enum多路分发 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值