首页 > 编程语言 > 详细

Java enum的用法详解

时间:2015-07-04 02:08:50      阅读:417      评论:0      收藏:0      [点我收藏+]

Java中枚举实现的分析:

? ? 示例:?

public static enum SEVERITY{
          INFO,WARN,ERROR
}

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

?

? ? SEVERITY字节码代码

// Signature: Ljava/lang/Enum<LSEVERITY;>;
public final enum SEVERITY {
  
  // Field descriptor #6 LSEVERITY;
  public static final enum SEVERITY INFO;
  
  // Field descriptor #6 LSEVERITY;
  public static final enum SEVERITY WARN;
  
  // Field descriptor #6 LSEVERITY;
  public static final enum SEVERITY ERROR;
  
  // Field descriptor #10 [LSEVERITY;
  private static final synthetic SEVERITY[] ENUM$VALUES;
  
  // Method descriptor #12 ()V
  // Stack: 4, Locals: 0
  static {};
     0  new SEVERITY [1]
     3  dup
     4  ldc <String "INFO"> [14]
     6  iconst_0
     7  invokespecial SEVERITY(java.lang.String, int) [15]
    10  putstatic SEVERITY.INFO : SEVERITY [19]
    13  new SEVERITY [1]
    16  dup
    17  ldc <String "WARN"> [21]
    19  iconst_1
    20  invokespecial SEVERITY(java.lang.String, int) [15]
    23  putstatic SEVERITY.WARN : SEVERITY [22]
    26  new SEVERITY [1]
    29  dup
    30  ldc <String "ERROR"> [24]
    32  iconst_2
    33  invokespecial SEVERITY(java.lang.String, int) [15]
    36  putstatic SEVERITY.ERROR : SEVERITY [25]
    39  iconst_3
    40  anewarray SEVERITY [1]
    43  dup
    44  iconst_0
    45  getstatic SEVERITY.INFO : SEVERITY [19]
    48  aastore
    49  dup
    50  iconst_1
    51  getstatic SEVERITY.WARN : SEVERITY [22]
    54  aastore
    55  dup
    56  iconst_2
    57  getstatic SEVERITY.ERROR : SEVERITY [25]
    60  aastore
    61  putstatic SEVERITY.ENUM$VALUES : SEVERITY[] [27]
    64  return
      Line numbers:
        [pc: 0, line: 4]
        [pc: 39, line: 2]
  
  // Method descriptor #18 (Ljava/lang/String;I)V
  // Stack: 3, Locals: 3
  private SEVERITY(java.lang.String arg0, int arg1);
    0  aload_0 [this]
    1  aload_1 [arg0]
    2  iload_2 [arg1]
    3  invokespecial java.lang.Enum(java.lang.String, int) [31]
    6  return
      Line numbers:
        [pc: 0, line: 2]
      Local variable table:
        [pc: 0, pc: 7] local: this index: 0 type: SEVERITY
  
  // Method descriptor #34 ()[LSEVERITY;
  // Stack: 5, Locals: 3
  public static SEVERITY[] values();
     0  getstatic SEVERITY.ENUM$VALUES : SEVERITY[] [27]
     3  dup
     4  astore_0
     5  iconst_0
     6  aload_0
     7  arraylength
     8  dup
     9  istore_1
    10  anewarray SEVERITY [1]
    13  dup
    14  astore_2
    15  iconst_0
    16  iload_1
    17  invokestatic java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int) : void [35]
    20  aload_2
    21  areturn
      Line numbers:
        [pc: 0, line: 1]
  
  // Method descriptor #42 (Ljava/lang/String;)LSEVERITY;
  // Stack: 2, Locals: 1
  public static SEVERITY valueOf(java.lang.String arg0);
     0  ldc <Class SEVERITY> [1]
     2  aload_0 [arg0]
     3  invokestatic java.lang.Enum.valueOf(java.lang.Class, java.lang.String) : java.lang.Enum [43]
     6  checkcast SEVERITY [1]
     9  areturn
      Line numbers:
        [pc: 0, line: 1]
}

? ? 不难看出所有的枚举值都是类静态常量。

?

? ?下面介绍enum的定义及用法

? ??1、SEVERITY枚举类是一个class,而且是一个不可以被继承的final类。其枚举值(INFO,WARN,ERROR)都是 ? ?SEVERITY类中静态常量,?我们可以通过下面的方式来得到SEVERITY枚举类的一个实例:

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

?

? ?2、因为枚举类是class,所以在枚举类型中有构造器,方法和数据域。但是枚举类的构造器有点不同:

?

public enum SEVERITY
{
    INFO("info"), WARN("warn"), ERROR("error");

    private SEVERITY(String code)
    {
        this.code = code;
    }

    public String toString()
    {
        return "(" + code + ")";
    }

    private String code;

    public String getCode()
    {
        return code;
    }

    public void setCode(String code)
    {
        this.code = code;
    }
}

? ??构造器只能私有(private),绝对不允许有public构造器。?这样可以保证外部代码无法新构造枚举类的实例。因为枚举值是public static final的常量。 但枚举类的方法和数据域可以允许外部访问。

?

? ? 3、所有枚举类都继承了Enum的方法,下面介绍这些方法:

? ? ? ? ?(1)? ordinal()方法: 返回枚举值在枚举类中的顺序,这个顺序根据枚举值声明的顺序而定。
? ? ? ? ? ? ? ? ?SEVERITY.INFO.ordinal();? //返回结果:0

? ? ? ? ?(2)? compareTo()方法: Enum实现了java.lang.Comparable接口,因此可以比较对象与指定对象的顺序。Enum中的compareTo返回的是两个枚举值的顺序之差。当然,前提是两个枚举值必须属于同一个枚举类,否则会抛出ClassCastException()异常。
? ? ? ? ? ? ? ? ?SEVERITY.INFO.compareTo(SEVERITY.WARN);? //返回结果 -1

? ? ? ? ?(3)? values()方法: 静态方法,返回一个包含全部枚举值的数组。
? ? ? ? ? ? ? ? ?SEVERITY[] s=SEVERITY.values();
? ? ? ? ?(4)? valueOf()方法: 返回带指定名称的指定枚举类型的枚举常量。
? ? ? ? ? ? ? ? ?SEVERITY.valueOf("ERROR");?? //返回结果:?SEVERITY.ERROR

? ? ? ? ?(5)? equals()方法: 比较两个枚举类对象的引用。

?

? ??4、枚举类可以在switch语句中使用。

?

SEVERITY severity =SEVERITY.ERROR;  
switch(severity){  
        case INFO: System.out.println("it‘s info");break;  
        case WARN: System.out.println("it‘s warn");break;  
        case ERROR: System.out.println("it‘s error");break;  
}  

?

?

? ? 5、实现接口

? ??所有的枚举都继承自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);
        }
    }

? ?

? ??6、使用接口组织枚举

?

    public interface Food {
        enum Coffee implements Food {
            BLACK_COFFEE, DECAF_COFFEE, LATTE, CAPPUCCINO
        }

        enum Dessert implements Food {
            FRUIT, CAKE, GELATO
        }
    }

?

? ? 7、关于枚举集合的使用

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

public class LightTest {

    // 1.定义枚举类型

    public enum Light {

        // 利用构造函数传参

        RED(1), GREEN(3), YELLOW(2);

        // 定义私有变量

        private int nCode;

        // 构造函数,枚举类型只能为私有

        private Light(int _nCode) {

            this.nCode = _nCode;

        }

        @Override
        public String toString() {

            return String.valueOf(this.nCode);

        }

    }

    /**
     * 
     * @param args
     */

    public static void main(String[] args) {

        // 1.遍历枚举类型

        System.out.println("演示枚举类型的遍历 ......");

        testTraversalEnum();

        // 2.演示EnumMap对象的使用

        System.out.println("演示EnmuMap对象的使用和遍历.....");

        testEnumMap();

        // 3.演示EnmuSet的使用

        System.out.println("演示EnmuSet对象的使用和遍历.....");

        testEnumSet();

    }

    /**
     * 
     * 演示枚举类型的遍历
     */

    private static void testTraversalEnum() {

        Light[] allLight = Light.values();

        for (Light aLight : allLight) {

            System.out.println("当前灯name:" + aLight.name());

            System.out.println("当前灯ordinal:" + aLight.ordinal());

            System.out.println("当前灯:" + aLight);

        }

    }

    /**
     * 
     * 演示EnumMap的使用,EnumMap跟HashMap的使用差不多,只不过key要是枚举类型
     */

    private static void testEnumMap() {

        // 1.演示定义EnumMap对象,EnumMap对象的构造函数需要参数传入,默认是key的类的类型

        EnumMap<Light, String> currEnumMap = new EnumMap<Light, String>(

        Light.class);

        currEnumMap.put(Light.RED, "红灯");

        currEnumMap.put(Light.GREEN, "绿灯");

        currEnumMap.put(Light.YELLOW, "黄灯");

        // 2.遍历对象

        for (Light aLight : Light.values()) {

            System.out.println("[key=" + aLight.name() + ",value="

            + currEnumMap.get(aLight) + "]");

        }

    }

    /**
     * 
     * 演示EnumSet如何使用,EnumSet是一个抽象类,获取一个类型的枚举类型内容<BR/>
     * 
     * 可以使用allOf方法
     */

    private static void testEnumSet() {

        EnumSet<Light> currEnumSet = EnumSet.allOf(Light.class);

        for (Light aLightSetElement : currEnumSet) {

            System.out.println("当前EnumSet中数据为:" + aLightSetElement);

        }

    }

}

? ?转载请注明出处:http://xieke90.iteye.com/blog/2224034

?

Java enum的用法详解

原文:http://xieke90.iteye.com/blog/2224034

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!