Java 枚舉(enum)詳解

 概念:

Java1.5發行版本中增加了新的引用類型--枚舉類型(enum type)。枚舉類型是指由一組固定的常量組成合法值的類型。在Java虛擬機中,枚舉類在進行編譯時會轉變成普通的Java類。

創建枚舉類型要使用enum關鍵字,隱含了所創建的類型都是java.lang.Enum類的子類(java.lang.Enum是一個抽象類)。枚舉類型的通用格式爲Class Enum<E extends Enum<E>>,而E表示枚舉類型的名稱。枚舉類型的每一個值都會映射到protected Enum(String name,int ordinal)構造函數中,在這裏,每個值的名稱都被轉換成一個字符串,並且序數設置表示了此設置被創建的順序。源碼如下:

/**
 * This is the common base class of all Java language enumeration types.
*/
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {
    private final String name;
    private final int ordinal;
    /**
     * Sole constructor.  Programmers cannot invoke this constructor.
     * It is for use by code emitted by the compiler in response to enum type declarations.
    */
    protected Enum(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }
}

以前我們定義常量都是: public static final....現在好了,當定義一個枚舉類型時,每一個枚舉類型成員都可以看作是 Enum 類的實例,這些枚舉成員默認都被 final、public, static 修飾,當使用枚舉類型成員時,直接使用枚舉名稱調用成員即可。

public enum Color {  
  RED, GREEN, BLANK, YELLOW  
}

方法介紹:

 

例 1

下面代碼定義了一個表示性別的枚舉類型 SexEnum 和一個表示顏色的枚舉類型 Color。

public enum SexEnum
{
    male,female;
}
public enum Color
{
    RED,BLUE,GREEN,BLACK;
}

之後便可以通過枚舉類型名直接引用常量,如 SexEnum.male、Color.RED。

使用枚舉還可以使 switch 語句的可讀性更強,例如以下示例代碼:

enum Signal
{
    //定義一個枚舉類型
    GREEN,YELLOW,RED
}
public class TrafficLight
{
    Signal color=Signal.RED;
    public void change()
    {
        switch(color)
        {
            case RED:
                color=Signal.GREEN;
                break;
            case YELLOW:
                color=Signal.RED;
                break;
            case GREEN:
                color=Signal.YELLOW;
                break;
        }
    }
}

例 2

通過調用枚舉類型實例的 values() 方法可以將枚舉的所有成員以數組形式返回,也可以通過該方法獲取枚舉類型的成員。

下面的示例創建一個包含 3 個成員的枚舉類型 Signal,然後調用 values() 方法輸出這些成員。

enum Signal
{
    //定義一個枚舉類型
    GREEN,YELLOW,RED;
}
public static void main(String[] args)
{
    for(int i=0;i<Signal.values().length;i++)
    {
        System.out.println("枚舉成員:"+Signal.values()[i]);
    }
}

輸出結果如下:

枚舉成員:GREEN
枚舉成員:YELLOW
枚舉成員:RED

例 3

創建一個示例,調用valueOf() 方法獲取枚舉的一個成員,再調用 compareTo() 方法進行比較,並輸出結果。具體實現代碼如下:

public class TestEnum
{
    public enum Sex
    {
        //定義一個枚舉
        male,female;
    }
    public static void main(String[] args)
    {
        compare(Sex.valueOf("male"));    //比較
    }
    public static void compare(Sex s)
    {
        for(int i=0;i<Sex.values().length;i++)
        {
            System.out.println(s+"與"+Sex.values()[i]+"的比較結果是:"+s.compareTo(Sex.values()[i]));
        }
    }
}

 

上述代碼中使用 Sex.valueOf("male") 取出枚舉成員 male 對應的值,再將該值與其他枚舉成員進行比較。最終輸出結果如下:

male與male的比較結果是:0
male與female的比較結果是:-1

例 4

通過調用枚舉類型實例的 ordinal() 方法可以獲取一個成員在枚舉中的索引位置。下面的示例創建一個包含 3 個成員的枚舉類型 Signal,然後調用 ordinal() 方法輸出成員及對應索引位置。

具體實現代碼如下:

public class TestEnum1
{
    enum Signal
    {
        //定義一個枚舉類型
        GREEN,YELLOW,RED;
    }
    public static void main(String[] args)
    {
        for(int i=0;i<Signal.values().length;i++)
        {
            System.out.println("索引"+Signal.values()[i].ordinal()+",值:"+Signal.values()[i]);
        }
    }
}

輸出結果如下:

索引0,值:GREEN
索引1,值:YELLOW
索引2,值:RED

爲枚舉添加方法

Java 爲枚舉類型提供了一些內置的方法,同時枚舉常量也可以有自己的方法。此時要注意必須在枚舉實例的最後一個成員後添加分號,而且必須先定義枚舉實例。

例 5

下面的代碼創建了一個枚舉類型 WeekDay,而且在該類型中添加了自定義的方法。

enum WeekDay
{
    Mon("Monday"),Tue("Tuesday"),Wed("Wednesday"),Thu("Thursday"),Fri("Friday"),Sat("Saturday"),Sun("Sunday");
    //以上是枚舉的成員,必須先定義,而且使用分號結束
    private final String day;
    private WeekDay(String day)
    {
        this.day=day;
    }
    public static void printDay(int i)
    {
        switch(i)
        {
            case 1:
                System.out.println(WeekDay.Mon);
                break;
            case 2:
                System.out.println(WeekDay.Tue);
                break;
            case 3:
                System.out.println(WeekDay.Wed);
                break;
            case 4:
                System.out.println(WeekDay.Thu);
                break;
            case 5:
                System.out.println(WeekDay.Fri);
                break;
            case 6:
                System.out.println(WeekDay.Sat);
                break;
            case 7:
                System.out.println(WeekDay.Sun);
                break;
            default:
                System.out.println("wrong number!");
        }
    }
    public String getDay()
    {
        return day;
    }
}

上面代碼創建了 WeekDay 枚舉類型,下面遍歷該枚舉中的所有成員,並調用 printDay() 方法。示例代碼如下:

public static void main(String[] args)
{
    for(WeekDay day:WeekDay.values())
    {
        System.out.println(day+"====>"+day.getDay());
    }
    WeekDay.printDay(5);
}

輸出結果如下:

Mon====>Monday
Tue====>Tuesday
Wed====>Wednesday
Thu====>Thursday
Fri====>Friday
Sat====>Saturday
Sun====>Sunday
Fri

Java 中的 enum 還可以跟 Class 類一樣覆蓋基類的方法。下面示例代碼創建的 Color 枚舉類型覆蓋了 toString() 方法。

public class Test
{
    public enum Color
    {
        RED("紅色",1),GREEN("綠色",2),WHITE("白色",3),YELLOW("黃色",4);
        //成員變量
        private String name;
        private int index;
        //構造方法
        private Color(String name,int index)
        {
            this.name=name;
            this.index=index;
        }
        //覆蓋方法
        @Override
        public String toString()
        {
            return this.index+"-"+this.name;
        }
    }
    public static void main(String[] args)
    {
        System.out.println(Color.RED.toString());    //輸出:1-紅色
    }
}

EnumMap 與 EnumSet

爲了更好地支持枚舉類型,java.util 中添加了兩個新類:EnumMap 和 EnumSet。使用它們可以更高效地操作枚舉類型。具體就後面再說吧。

發佈了81 篇原創文章 · 獲贊 15 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章