java enum(枚举)使用详解 + 总结

来源:互联网 发布:java 开源项目管理 编辑:程序博客网 时间:2024/06/07 02:24

转:http://blog.csdn.net/qiyueqinglian/article/details/50738548


DK1.5引入了新的类型——枚举。在 Java 中它虽然算个“小”功能,却给我的开发带来了“大”方便。 
接下来,我以自定义的枚举类LightsEnum.java和LightsEnumWithValue.java来介绍一下枚举类的使用。 
LightsEnum.java

package enums;public enum LightsEnum {    RED, YELLOW, GREEN}
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

用法一:定义常量

在JDK1.5 之前,我们定义常量都是: public static fianl…. 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。 
通过类名就可以直接引用这些常量,比如:LightsEnum.YELLOW

// 遍历enumLightsEnum[] lightsEnumArr = LightsEnum.values();for (LightsEnum e : lightsEnumArr) {    System.out.println(e.toString());}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

运行结果: 
RED 
YELLOW 
GREEN

用法二:与switch结合

JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。

LightsEnum currentLight = LightsEnum.YELLOW;switch (currentLight) {case RED:    System.out.println("this is the red light");    break;case YELLOW:    System.out.println("this is the yellow light");    break;case GREEN:    System.out.println("this is the green light");    break;default:    break;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

运行结果:this is the yellow light

用法三:给 enum 自定义属性和方法

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

package enums;public enum LightsEnumWithValue {    RED("红灯"), YELLOW("黄灯"), GREEN("绿灯");    // 自定义变量    private String value;    // 自定义普通成员方法    public String getValue() {        return value;    }    // 构造方法    LightsEnumWithValue(String value) {        this.value = value;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

使用自定义的变量

LightsEnumWithValue[] lightsEnumWithValueArr = LightsEnumWithValue                .values();for (LightsEnumWithValue e : lightsEnumWithValueArr) {    System.out.println("toString: " + e.toString());    System.out.println("getValue: " + e.getValue());}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

运行结果: 
toString: RED 
getValue: 红灯 
toString: YELLOW 
getValue: 黄灯 
toString: GREEN 
getValue: 绿灯

用法四:覆盖枚举的方法

package enums;public enum LightsEnumWithValue {    RED("红灯"), YELLOW("黄灯"), GREEN("绿灯");    // 自定义变量    private String value;    // 自定义普通成员方法    public String getValue() {        return value;    }    // 构造方法    LightsEnumWithValue(String value) {        this.value = value;    }    // 覆盖方法    @Override    public String toString() {        return this.name() + "_" + this.value;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

调用覆盖之后的toString方法

LightsEnumWithValue[] lightsEnumWithValueArr = LightsEnumWithValue                .values();for (LightsEnumWithValue e : lightsEnumWithValueArr) {    System.out.println("toString: " + e.toString());    System.out.println("getValue: " + e.getValue());}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

运行结果(注意和用法三中的toString得到的结果不一样了): 
toString: RED_红灯 
getValue: 红灯 
toString: YELLOW_黄灯 
getValue: 黄灯 
toString: GREEN_绿灯 
getValue: 绿灯

用法五:实现接口

所有的枚举都继承自java.lang.Enum类。由于Java 不支持多继承,所以枚举对象不能再继承其他类。

public interface Behaviour {      void print();      String getInfo();  }  public enum Color implements Behaviour{      RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);      // 成员变量      private String name;      private int index;      // 构造方法      private Color(String name, int index) {          this.name = name;          this.index = index;      }      //接口方法      @Override      public String getInfo() {          return this.name;      }      //接口方法      @Override      public void print() {          System.out.println(this.index+":"+this.name);      }  }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

用法六:使用接口组织枚举

public interface Food {      enum Coffee implements Food{          BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO      }      enum Dessert implements Food{          FRUIT, CAKE, GELATO      }  }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
如:Food f = Food.Coffee.BLACK_COFFEE;

用法七:EnumSet,EnumMap 的应用

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

EnumSet<LightsEnum> lightsEnumSet = EnumSet.allOf(LightsEnum.class);for (LightsEnum l : lightsEnumSet) {    System.out.println(l.toString());}System.out.println("------------------EnumMap");EnumMap<LightsEnum, String> lightsEnumMap = new EnumMap<LightsEnum, String>(        LightsEnum.class);lightsEnumMap.put(LightsEnum.RED, "红灯");Set<Entry<LightsEnum, String>> set = lightsEnumMap.entrySet();Iterator<Entry<LightsEnum, String>> iterator = set.iterator();while (iterator.hasNext()) {    Entry<LightsEnum, String> e = iterator.next();    System.out.println(e.getKey().toString() + ":" + e.getValue());}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

运行结果: 
——————EnumSet 
RED 
YELLOW 
GREEN 
——————EnumMap 
RED:红灯

enum总结及常用方法

可以把 enum 看成是一个普通的 class,可以定义一些属性和方法,实现接口,不同之处是:enum 不能使用 extends 关键字继承其他类,因为 enum 已经继承了 java.lang.Enum(java是单一继承)

// int ordinal() 返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。System.out.println("red ordinal: " + LightsEnum.RED.ordinal());System.out.println("yellow ordinal: " + LightsEnum.YELLOW.ordinal());System.out.println("green ordinal: " + LightsEnum.GREEN.ordinal());// int compareTo(E o) 比较此枚举与指定对象的顺序int compToRed = currentLight.compareTo(LightsEnum.RED);int compToYellow = currentLight.compareTo(LightsEnum.YELLOW);int compToGreen = currentLight.compareTo(LightsEnum.GREEN);System.out.println("yellow compare to red: " + compToRed);System.out.println("yellow compare to yellow: " + compToYellow);System.out.println("yellow compare to green: " + compToGreen);// String name() 返回此枚举常量的名称,在其枚举声明中对其进行声明System.out.println("name: " + currentLight.name());// String toString() 返回枚举常量的名称,它包含在声明中System.out.println("toString: " + currentLight.toString());// Class<E> getDeclaringClass() 返回与此枚举常量的枚举类型相对应的 Class 对象。System.out.println("getDeclaringClass(): "        + currentLight.getDeclaringClass().getName());// static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)// 返回带指定名称的指定枚举类型的枚举常量。System.out.println(LightsEnum.valueOf(LightsEnum.class, "YELLOW"));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

运行结果: 
red ordinal: 0 
yellow ordinal: 1 
green ordinal: 2 
yellow compare to red: 1 
yellow compare to yellow: 0 
yellow compare to green: -1 
name: YELLOW 
toString: YELLOW 
getDeclaringClass(): enums.LightsEnum 
YELLOW

enum原理

语法(定义) 
创建枚举类型要使用 enum 关键字,隐含了所创建的类型都是 java.lang.Enum 类的子类(java.lang.Enum 是一个抽象类)。枚举类型符合通用模式 Class Enum<E extends Enum<E>>,而 E 表示枚举类型的名称。枚举类型的每一个值都将映射到 protected Enum(String name, int ordinal)构造函数中,在这里,每个值的名称都被转换成一个字符串,并且序数设置表示了此设置被创建的顺序。 
enum 的语法结构尽管和 class 的语法不一样,但是经过编译器编译之后产生的是一个class文件。该class文件经过反编译可以看到实际上是生成了一个类,该类继承了java.lang.Enum。LightsEnum.java和LightsEnumWithValue.java经过反编译(javap enums.LightsEnumWithValue 命令)之后得到的内容如下。 
这两个enum反编译之后的主要不同是构造函数,LightsEnumWithValue.java中还含有自定义的方法。

private LightsEnum(String s, int i)    {        super(s, i);    }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4
private LightsEnumWithValue(String s, int i, String value)    {        super(s, i);        this.value = value;    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

LightsEnum.class

// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.// Jad home page: http://kpdus.tripod.com/jad.html// Decompiler options: packimports(3) fieldsfirst ansi space // Source File Name:   LightsEnum.javapackage enums;public final class LightsEnum extends Enum{    public static final LightsEnum RED;    public static final LightsEnum YELLOW;    public static final LightsEnum GREEN;    private static final LightsEnum ENUM$VALUES[];    private LightsEnum(String s, int i)    {        super(s, i);    }    public static LightsEnum[] values()    {        LightsEnum alightsenum[];        int i;        LightsEnum alightsenum1[];        System.arraycopy(alightsenum = ENUM$VALUES, 0, alightsenum1 = new LightsEnum[i = alightsenum.length], 0, i);        return alightsenum1;    }    public static LightsEnum valueOf(String s)    {        return (LightsEnum)Enum.valueOf(enums/LightsEnum, s);    }    static     {        RED = new LightsEnum("RED", 0);        YELLOW = new LightsEnum("YELLOW", 1);        GREEN = new LightsEnum("GREEN", 2);        ENUM$VALUES = (new LightsEnum[] {            RED, YELLOW, GREEN        });    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

LightsEnumWithValue.class

// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.// Jad home page: http://kpdus.tripod.com/jad.html// Decompiler options: packimports(3) fieldsfirst ansi space // Source File Name:   LightsEnumWithValue.javapackage enums;public final class LightsEnumWithValue extends Enum{    public static final LightsEnumWithValue RED;    public static final LightsEnumWithValue YELLOW;    public static final LightsEnumWithValue GREEN;    private String value;    private static final LightsEnumWithValue ENUM$VALUES[];    public String getValue()    {        return value;    }    private LightsEnumWithValue(String s, int i, String value)    {        super(s, i);        this.value = value;    }    public static LightsEnumWithValue[] values()    {        LightsEnumWithValue alightsenumwithvalue[];        int i;        LightsEnumWithValue alightsenumwithvalue1[];        System.arraycopy(alightsenumwithvalue = ENUM$VALUES, 0, alightsenumwithvalue1 = new LightsEnumWithValue[i = alightsenumwithvalue.length], 0, i);        return alightsenumwithvalue1;    }    public static LightsEnumWithValue valueOf(String s)    {        return (LightsEnumWithValue)Enum.valueOf(enums/LightsEnumWithValue, s);    }    static     {        RED = new LightsEnumWithValue("RED", 0, "红灯");        YELLOW = new LightsEnumWithValue("YELLOW", 1, "黄灯");        GREEN = new LightsEnumWithValue("GREEN", 2, "绿灯");        ENUM$VALUES = (new LightsEnumWithValue[] {            RED, YELLOW, GREEN        });    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

参照: 
http://www.cnblogs.com/hemingwang0902/archive/2011/12/29/2306263.html 
http://blog.lichengwu.cn/java/2011/09/26/the-usage-of-enum-in-java/


原创粉丝点击