1. 程式人生 > >枚舉類型

枚舉類型

out row msg 不能 num pack gree 有效 status

創建一個枚舉類的時候默認繼承Enum,所以無法再繼承其他的類,但是可以實現多個接口。而且編譯器編譯的時候會將枚舉類標記為final所以也不會被繼承,以下是一個最基礎的枚舉類

package cn.ghaien.demo;
public enum EnumDemo1 {
    OBJECT_1, OBJECT_2, OBJECT_3
}

使用javac編譯後

package cn.ghaien.demo;

public enum EnumDemo1 {
    OBJECT_1,
    OBJECT_2,
    OBJECT_3;

    private EnumDemo1() {
    }
}

再使用javap進行反編譯

public final class cn.ghaien.demo.EnumDemo1 extends java.lang.Enum<cn.ghaien.demo.EnumDemo1> {
  public static final cn.ghaien.demo.EnumDemo1 OBJECT_1;
  public static final cn.ghaien.demo.EnumDemo1 OBJECT_2;
  public static final cn.ghaien.demo.EnumDemo1 OBJECT_3;
  public static
cn.ghaien.demo.EnumDemo1[] values(); public static cn.ghaien.demo.EnumDemo1 valueOf(java.lang.String); static {}; }

枚舉類常用的方法


  • name:獲取某個實例聲明時的名稱
  • ordinal:獲取某個實例在枚舉類中聲明的序號(從0開始)
  • compareTo:通過實例在枚舉類中的聲明順序進行比較大小
  • getDeclaringClass:返回某個實例的Class對象
  • valueOf:Enum中的方法需要傳兩個參數一個是枚舉類的Class對象一個是實例的名稱,返回該實例對象
  • equal:比較是否是同一個對象,即使用‘==’比較
  • toString:返回實例的名稱
    System.out.println(EnumDemo1.OBJECT_1.name());
    System.out.println(EnumDemo1.OBJECT_2.ordinal());
    System.out.println(EnumDemo1.OBJECT_3.getDeclaringClass());
    System.out.println(EnumDemo1.OBJECT_2.compareTo(EnumDemo1.OBJECT_3));
    System.out.println(EnumDemo1.OBJECT_1.equals(EnumDemo1.OBJECT_2));
    System.out.println(EnumDemo1.valueOf(EnumDemo1.class, "OBJECT_2"));
    /** output
     *  OBJECT_1
     *  1
     *  class cn.ghaien.demo.EnumDemo1
     *  -1
     *  false
     *  OBJECT_2
     */

    以上這些方法都是Enum類中的方法,從上面反編譯後的代碼可以看出,當創建一個枚舉類的時候編譯器會自動幫你添加以下兩個方法

  • values:返回枚舉類中所有實例的數組
  • valueOf:該方法只有一個字符串類型的參數, 返回名稱為該參數的實例
    EnumDemo1[] values = EnumDemo1.values();
    for (EnumDemo1 value : values)
        System.out.print(value.name() + " ");
    System.out.println("\n" + EnumDemo1.valueOf("OBJECT_1"));
    /**
     * OBJECT_1 OBJECT_2 OBJECT_3
     * OBJECT_1 
     */

枚舉類與switch


在switch中使用enum,是enum提供的一個非常有用的功能。一般來說在switch中只能使用整數值,而枚舉類中的每個實例都具有一個整數值的次序,即通過ordinal方法獲得,使得enum可以與switch結合使用

enum Color {
    RED, YELLOW
}
public class TrangeColor {
    Color color = Color.RED;
    public void change() {
        switch(color) {   
            case RED: //這裏不能使用Color.RED
                color = Color.YELLOW;
                break;
            case YELLOW:
                color = Color.RED;
                break;
        }
    }
}            

枚舉類中重載構造器


與普通的類一樣,編譯器會幫我們自動生成一個默認的無參構造器,而且我們也可以重載多個構造器。在日常的開發中我們經常需要將某個狀態值與狀態信息進行綁定,我們就可以通過在枚舉類中重載構造器來實現這個功能,代碼如下

public enum StatusEnum {
    INVALID(1, "失效"),
    VALID(2, "有效");
    private Integer value;
    private String msg;
    StatusEnum(Integer value, String msg) {
        this.value = value;
        this.msg = msg;
    }
    public static String getMsgByValue(Integer value) {
        StatusEnum[] status = StatusEnum.values();
        for (StatusEnum statu : status) {
            if (statu.value.equals(value)) {
                return statu.msg;
            }
        }
        throw new RuntimeException("錯誤的value值");
    }
}

通過調用getMsgByValue方法我們就可以獲取某個狀態值對應的狀態信息,當然我們也可以直接將實例的名稱命名為狀態的信息,這樣我們就可以只需要含有一個參數的構造器來實現這個功能

註意:若想在枚舉類中定義屬性或方法,那必須在枚舉實例序列的最後一個後面加上‘;’,並且只能放在在枚舉實例序列的後面,否則會直接編譯錯誤。枚舉類中的構造器只能在其內部創建實例。

枚舉類與抽象方法


在枚舉類中可以直接定義抽象方法,但是每個實例必須得實現所有的抽象方法,否則編譯錯誤,枚舉類中的實例實現抽象方法的代碼如下

public enum ColorEnum {
    RED {
        public String getColor() { return "紅色"; }
    },
    GREEN {
        public String getColor() { return "綠色"; }
    },
    BALCK {
        public String getColor() { return "黑色"; }
    };
    abstract String getColor();
}

枚舉類型