Java枚舉類型enum

來源:互聯網
上載者:User

Java枚舉類型enum
枚舉的文法
1.Enum的全稱為enumeration,中文俗稱枚舉類,學過C/C++等語言的人,應該都對它略知一二。
但在Java語言規範中,是在JDK 5版本中才引入的,存放在 java.lang 包中。在Java版的Enum實質是文法糖,其聲明方式如下:

【代碼1】

 

package com.enumtest;public enum Color{    RED,BLUE,BLACK,YELLOW,GREEN   //注意這裡可以沒有分號}   
enum是用來聲明枚舉的關鍵字,聲明定義的類都隱含繼承了一個父類(java.lang.Enum),因此枚舉不能再繼承,但仍可實現介面。
該父類有兩個私人屬性name(枚舉類型的名稱)和ordinal(枚舉執行個體被建立的序數),分別通過name()和ordinal()暴露出來了.
定義在枚舉類型裡的每一個枚舉執行個體都將映射到Enum的子類中,其執行個體的名稱和在枚舉類型裡定義的順序都會傳入到這個建構函式裡 : protected Enum(String name, int ordinal)。
2.如果想更清楚瞭解一下Enum,可以用反編譯工具把自己定義的枚舉反編譯一下就一目瞭然了,它就是一個普通的類,只是Java語言規範從Code角度進行了限制,執行javap com.enumtest.Color命令如下:
【代碼2】
package com.enumtest;  public final class Color extends  java.lang.Enum{     public static final Color RED;     public static final Color BLUE;     public static final Color BLACK;     public static final Color YELLOW;     public static final Color GREEN;     static {};     public static Color[] values();     public static Color valueOf(java.lang.String); } 
3.所有枚舉類都繼承了Enum的方法,下面我們詳細介紹這些方法。
(1) ordinal()方法: 返回枚舉值在枚舉類種的順序。這個順序根據枚舉值聲明的順序而定。
Color.RED.ordinal(); //返回結果:0
Color.BLUE.ordinal(); //返回結果:1
(2) compareTo()方法: Enum實現了java.lang.Comparable介面,因此可以比較象與指定對象的順序。Enum中的compareTo返回的是兩個枚舉值的順序之差。當然,前提是兩個枚舉值必須屬於同一個枚舉類,否則會拋出ClassCastException()異常。(具體可見原始碼)
Color.RED.compareTo(Color.BLUE); //返回結果 -1
(3) values()方法: 靜態方法,返回一個包含全部枚舉值的數組。
Color[] colors=Color.values();
for(Color c:colors){
System.out.print(c+",");
}//返回結果:RED,BLUE,BLACK YELLOW,GREEN,
(4) toString()方法: 返回枚舉常量的名稱。
Color c=Color.RED;
System.out.println(c);//返回結果: RED
(5) valueOf()方法: 這個方法和toString方法是相對應的,返回帶指定名稱的指定枚舉類型的枚舉常量。
Color.valueOf("BLUE"); //返回結果: Color.BLUE
(6) equals()方法: 比較兩個枚舉類對象的引用。
4. 如果定義的枚舉有自己的建構函式必須聲明私人的。

5. 注意以下區別:
【代碼3】

enum Color3{}enum Color4{    RED}enum Color5{    RED;}enum Color6{    RED;    public void test(){}}enum Color7{    public void test(){}   // RED;  //錯誤!!!!}enum Color8{    ;    public void test(){}}
在enum Color3中是一個空的枚舉;在enum Color4和Color5中有一個RED的枚舉值,後面可以加分號或者不加分號;如果在枚舉值後面添加方法,那麼在枚舉值的最後添加一個分號,如enum Color6;如果像enum Color7一樣想把枚舉值定義在方法後面是非法的,編譯器會提示錯誤;當然也可以像enum Color8一樣定義,注意方法test()之前的分號。

 

枚舉的用法
(1) 常用於對同一類常量進行分類。見代碼1.
(2) 聲明介面方法時,輸入參數類型採用枚舉比用原始類型值常量更嚴謹.
(3) 常量有時往往不僅僅只是一個值,有可能會包含多個屬性,此時很適合用枚舉
(4) 有時常量對象需要從設定檔中讀取其描述資訊或者UI顯示資訊,此時也適合用枚舉
(5) 從Java文法層面來說,枚舉可以在switch使用,在if中可直接進行比較 。
【代碼4】

 

package com.enumtest;public enum Color {    RED,BLUE,BLACK,YELLOW,GREEN; //注意這裡有分號    public static void valuePrint(Color color)    {        switch(color)        {            case RED:                System.out.println(RED);                break;            case BLUE:                System.out.println(BLUE);                break;            case BLACK:                System.out.println(BLACK);                break;            case YELLOW:                System.out.println(YELLOW);                break;            case GREEN:                System.out.println(GREEN);                break;            default:                break;        }    }    public static void main(String args[])    {        Color color = Color.RED;        valuePrint(color);        EnumTest.valuePrint(color);    }}class EnumTest{    public static void valuePrint(Color color)    {        switch(color)        {            case RED:                System.out.println(Color.RED);//注意這裡的Color.RED不能寫成RED,而case中的必須寫成RED。                break;            case BLUE:                System.out.println(Color.BLUE);                break;            case BLACK:                System.out.println(Color.BLACK);                break;            case YELLOW:                System.out.println(Color.YELLOW);                break;            case GREEN:                System.out.println(Color.GREEN);                break;            default:                break;        }    }}
運行結果:
REDRED
(6) 聲明枚舉屬性時最好用public final修飾,使用起來會非常方便
(7) 自訂枚舉時,建議不要使用內建的name()和ordinal()方法傳回值來與原始實值型別轉換,這樣業務不依賴其枚舉的名字和順序
【代碼5】
package com.enumtest;public enum Color2{    RED("紅色",1),BLUE("藍色",2),BLACK("黑色",3),YELLOW("黃色",4),GREEN("綠色",5);    public final String name;    public final int index;    private Color2(String name, int index)    {        this.name = name;        this.index = index;    }    public static String getName(int index)    {        for(Color2 c: Color2.values())        {            if(c.getIndex() == index)            {                return c.name;            }        }        return null;    }    public static void main(String[] args)    {        System.out.println(getName(1));    }    public String getName()    {        return name;    }    public int getIndex()    {        return index;    }}
運行結果:紅色
(8) 重載枚舉的方法toString
【代碼6】

 

 

package com.enumtest;public enum Color2{    RED("紅色",1),BLUE("藍色",2),BLACK("黑色",3),YELLOW("黃色",4),GREEN("綠色",5);    public final String name;    public final int index;    private Color2(String name, int index)    {        this.name = name;        this.index = index;    }    public static String getName(int index)    {        for(Color2 c: Color2.values())        {            if(c.getIndex() == index)            {                return c.toString();            }        }        return null;    }    public static void main(String[] args)    {        System.out.println(getName(1));    }    @Override    public String toString()    {        return this.index+"_"+this.name;    }    public String getName()    {        return name;    }    public int getIndex()    {        return index;    }}
(9)實現介面。所有的枚舉都繼承自java.lang.Enum類。由於java不支援多繼承,所以枚舉對象不能再繼承其他的類。
【代碼7】
package com.enumtest;public interface Behaviour{    void print();    String getInfo();}
【代碼8】
package com.enumtest;public enum Color9 implements Behaviour{    RED("紅色",1),BLUE("藍色",2),BLACK("黑色",3),YELLOW("黃色",4),GREEN("綠色",5);    public final String name;    public final int index;    private Color9(String name, int index)    {        this.name = name;        this.index = index;    }    @Override    public void print()    {        System.out.println(this.index+":"+this.name);    }    @Override    public String getInfo()    {        return this.name;    }}
(10) 可以建立一個enum類,把它看做一個普通的類。除了它不能繼承其他類。(Java是單繼承,它已經繼承了Enum),可以添加其他的方法,覆蓋它本身的方法。
(11) values()方法是編譯器插入到enum定義中的static方法,所以,當你將enum執行個體向上轉型為父類Enum是,values()就不可訪問了。解決辦法:在Class中有一個getEnumConstants()方法,所以即便Enum介面中沒有values()方法,我們仍然可以通過Class對象取得所有的enum執行個體。
【代碼9】
package com.enumtest;public enum Color {    RED,BLUE,BLACK,YELLOW,GREEN; //注意這裡有分號    public void print()    {        for(Color c : Color.class.getEnumConstants())        {            System.out.println(c.toString());        }    }    public static void main(String args[])    {        Color.RED.print();    }}
(12) 無法從enum繼承子類,如果需要擴充enum中的元素,在一個介面的內部,建立實現該介面的枚舉,以此將元素進行分組。達到將枚舉元素進行分組。
【代碼10】
package com.enumtest;public interface Food{    enum Coffee implements Food     {        BLACK_COFFEE, DECAF_COFFEE,LATTE;    }    enum Dessert implements Food    {        FRUIT,CAKE,GELATO;    }}
(13) java.util.EnumSet和java.util.EnumMap是兩個枚舉集合。EnumSet保證集合中的元素不重複;EnumMap中的 key是enum類型,而value則可以是任意類型。
【代碼11】
package com.enumtest;import java.util.EnumMap;import java.util.EnumSet;import java.util.Set;public class LightTest{    public enum Light{        RED(1),GREEN(2),YELLOW(3);        public final int nCode;        private Light(int nCode)        {            this.nCode = nCode;        }    }    public static void testTraversalEnum()    {        Light[] allLight = Light.values();        for(Light aLight:allLight)        {            System.out.println(aLight.name()+" "+aLight.ordinal()+" "+aLight);        }    }    public static void testEnumMap()    {        EnumMap currEnumMap = new EnumMap(Light.class);        currEnumMap.put(Light.RED, "紅色");        currEnumMap.put(Light.GREEN, "綠色");        currEnumMap.put(Light.YELLOW, "黃色");        Set set = currEnumMap.keySet();        for(Light aLight:set)        {            System.out.println(aLight.name()+" "+aLight.ordinal()+" "+aLight);        }    }    public static void testEnumSet()    {        EnumSet currEnumSet = EnumSet.allOf(Light.class);        for(Light aLightSetElement : currEnumSet)        {            System.out.println(aLightSetElement);        }    }    public static void main(String[] args)    {        testTraversalEnum();        testEnumMap();        testEnumSet();    }}
運行結果:(略)
(14) 使用enum的職責鏈(Chain of Responsibility) .這個關係到設計模式的職責鏈模式。以多種不同的方法來解決一個問題。然後將他們連結在一起。當一個請求到來時,遍曆這個鏈,直到鏈中的某個解決方案能夠處理該請求。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.