Java枚舉用法詳解

用法一:常量

在JDK1.5 之前,我們定義常量都是: public static fianl.... √雀校現(xiàn)在好了留特,有了枚舉,可以把相關(guān)的常量分組到一個(gè)枚舉類型里孩哑,而且枚舉提供了比常量更多的方法栓霜。

1
2
3
public enum Color {
RED, GREEN, BLANK, YELLOW
}
用法二:switch

JDK1.6之前的switch語(yǔ)句只支持int,char,enum類型,使用枚舉横蜒,能讓我們的代碼可讀性更強(qiáng)胳蛮。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;
        }
    }
}

用法三:向枚舉中添加新方法

如果打算自定義自己的方法,那么必須在enum實(shí)例序列的最后添加一個(gè)分號(hào)丛晌。而且 Java 要求必須先定義 enum 實(shí)例仅炊。

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
public enum Color {
RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4);
// 成員變量
private String name;
private int index;

    // 構(gòu)造方法
    private Color(String name, int index) {
        this.name = name;
        this.index = index;
    }

    // 普通方法
    public static String getName(int index) {
        for (Color c : Color.values()) {
            if (c.getIndex() == index) {
                return c.name;
            }
        }
        return null;
    }

    // get set 方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }
}

用法四:覆蓋枚舉的方法

下面給出一個(gè)toString()方法覆蓋的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Test {
public enum Color {
RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4);
// 成員變量
private String name;
private int index;

    // 構(gòu)造方法
    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());
}

}
用法五:實(shí)現(xiàn)接口

所有的枚舉都繼承自java.lang.Enum類澎蛛。由于Java 不支持多繼承抚垄,所以枚舉對(duì)象不能再繼承其他類。

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
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;

    // 構(gòu)造方法
    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
public interface Food {
enum Coffee implements Food {
BLACK_COFFEE, DECAF_COFFEE, LATTE, CAPPUCCINO
}

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

用法七:關(guān)于枚舉集合的使用

java.util.EnumSet和java.util.EnumMap是兩個(gè)枚舉集合瓶竭。EnumSet保證集合中的元素不重復(fù);EnumMap中的 key是enum類型督勺,而value則可以是任意類型。關(guān)于這個(gè)兩個(gè)集合的使用就不在這里贅述斤贰,可以參考JDK文檔

枚舉和常量定義的區(qū)別

一智哀、 通常定義常量方法

我們通常利用public final static方法定義的代碼如下,分別用1表示紅燈荧恍,3表示綠燈瓷叫,2表示黃燈。

1
2
3
4
5
6
7
8
9
10
public class Light {
/* 紅燈 */
public final static int RED = 1;

    /* 綠燈 */
    public final static int GREEN = 3;

    /* 黃燈 */
    public final static int YELLOW = 2;
}

二送巡、 枚舉類型定義常量方法

枚舉類型的簡(jiǎn)單定義方法如下摹菠,我們似乎沒(méi)辦法定義每個(gè)枚舉類型的值。比如我們定義紅燈骗爆、綠燈和黃燈的代碼可能如下:

1
2
3
public enum Light {
RED, GREEN, YELLOW;
}
我們只能夠表示出紅燈次氨、綠燈和黃燈,但是具體的值我們沒(méi)辦法表示出來(lái)摘投。別急煮寡,既然枚舉類型提供了構(gòu)造函數(shù)虹蓄,我們可以通過(guò)構(gòu)造函數(shù)和覆寫toString方法來(lái)實(shí)現(xiàn)。首先給Light枚舉類型增加構(gòu)造方法幸撕,然后每個(gè)枚舉類型的值通過(guò)構(gòu)造函數(shù)傳入對(duì)應(yīng)的參數(shù)薇组,同時(shí)覆寫toString方法,在該方法中返回從構(gòu)造函數(shù)中傳入的參數(shù)坐儿,改造后的代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public enum Light {

// 利用構(gòu)造函數(shù)傳參
RED(1), GREEN(3), YELLOW(2);

// 定義私有變量
private int nCode;

// 構(gòu)造函數(shù)律胀,枚舉類型只能為私有
private Light(int _nCode) {

    this.nCode = _nCode;

}

@Override
public String toString() {

    return String.valueOf(this.nCode);

}

}
三、 完整示例代碼

枚舉類型的完整演示代碼如下:

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
public class LightTest {

// 1.定義枚舉類型

public enum Light {

    // 利用構(gòu)造函數(shù)傳參

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

    // 定義私有變量

    private int nCode;

    // 構(gòu)造函數(shù)貌矿,枚舉類型只能為私有

    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對(duì)象的使用

    System.out.println("演示EnmuMap對(duì)象的使用和遍歷.....");

    testEnumMap();

    // 3.演示EnmuSet的使用

    System.out.println("演示EnmuSet對(duì)象的使用和遍歷.....");

    testEnumSet();

}

/**
 * 
 * 演示枚舉類型的遍歷
 */

private static void testTraversalEnum() {

    Light[] allLight = Light.values();

    for (Light aLight : allLight) {

        System.out.println("當(dāng)前燈name:" + aLight.name());

        System.out.println("當(dāng)前燈ordinal:" + aLight.ordinal());

        System.out.println("當(dāng)前燈:" + aLight);

    }

}

/**
 * 
 * 演示EnumMap的使用炭菌,EnumMap跟HashMap的使用差不多,只不過(guò)key要是枚舉類型
 */

private static void testEnumMap() {

    // 1.演示定義EnumMap對(duì)象站叼,EnumMap對(duì)象的構(gòu)造函數(shù)需要參數(shù)傳入,默認(rèn)是key的類的類型

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

    Light.class);

    currEnumMap.put(Light.RED, "紅燈");

    currEnumMap.put(Light.GREEN, "綠燈");

    currEnumMap.put(Light.YELLOW, "黃燈");

    // 2.遍歷對(duì)象

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

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

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

    }

}

/**
 * 
 * 演示EnumSet如何使用娃兽,EnumSet是一個(gè)抽象類,獲取一個(gè)類型的枚舉類型內(nèi)容<BR/>
 * 
 * 可以使用allOf方法
 */

private static void testEnumSet() {

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

    for (Light aLightSetElement : currEnumSet) {

        System.out.println("當(dāng)前EnumSet中數(shù)據(jù)為:" + aLightSetElement);

    }

}

}
執(zhí)行結(jié)果如下:

演示枚舉類型的遍歷 ......

當(dāng)前燈name:RED

當(dāng)前燈ordinal:0

當(dāng)前燈:1

當(dāng)前燈name:GREEN

當(dāng)前燈ordinal:1

當(dāng)前燈:3

當(dāng)前燈name:YELLOW

當(dāng)前燈ordinal:2

當(dāng)前燈:2

演示EnmuMap對(duì)象的使用和遍歷.....

[key=RED,value=紅燈]

[key=GREEN,value=綠燈]

[key=YELLOW,value=黃燈]

演示EnmuSet對(duì)象的使用和遍歷.....

當(dāng)前EnumSet中數(shù)據(jù)為:1

當(dāng)前EnumSet中數(shù)據(jù)為:3

當(dāng)前EnumSet中數(shù)據(jù)為:2

四尽楔、 通常定義常量方法和枚舉定義常量方法區(qū)別

以下內(nèi)容可能有些無(wú)聊投储,但絕對(duì)值得一窺

  1. 代碼:

1
2
3
4
5
6
7
public class State {

public static final int ON = 1;

public static final Int OFF= 0;

}
有什么不好了,大家都這樣用了很長(zhǎng)時(shí)間了阔馋,沒(méi)什么問(wèn)題啊玛荞。

首先,它不是類型安全的呕寝。你必須確保是int

其次勋眯,你還要確保它的范圍是0和1

最后,很多時(shí)候你打印出來(lái)的時(shí)候下梢,你只看到 1 和0 客蹋,

但其沒(méi)有看到代碼的人并不知道你的企圖,拋棄你所有舊的public static final常量

  1. 可以創(chuàng)建一個(gè)enum類孽江,把它看做一個(gè)普通的類讶坯。除了它不能繼承其他類了。(java是單繼承岗屏,它已經(jīng)繼承了Enum),

可以添加其他方法辆琅,覆蓋它本身的方法

  1. switch()參數(shù)可以使用enum了

  2. values()方法是編譯器插入到enum定義中的static方法,所以这刷,當(dāng)你將enum實(shí)例向上轉(zhuǎn)型為父類Enum是婉烟,values()就不可訪問(wèn)了。解決辦法:在Class中有一個(gè)getEnumConstants()方法暇屋,所以即便Enum接口中沒(méi)有values()方法似袁,我們?nèi)匀豢梢酝ㄟ^(guò)Class對(duì)象取得所有的enum實(shí)例

  3. 無(wú)法從enum繼承子類,如果需要擴(kuò)展enum中的元素,在一個(gè)接口的內(nèi)部叔营,創(chuàng)建實(shí)現(xiàn)該接口的枚舉屋彪,以此將元素進(jìn)行分組所宰。達(dá)到將枚舉元素進(jìn)行分組绒尊。

  4. 使用EnumSet代替標(biāo)志。enum要求其成員都是唯一的仔粥,但是enum中不能刪除添加元素婴谱。

  5. EnumMap的key是enum,value是任何其他Object對(duì)象躯泰。

  6. enum允許程序員為eunm實(shí)例編寫方法谭羔。所以可以為每個(gè)enum實(shí)例賦予各自不同的行為。

  7. 使用enum的職責(zé)鏈(Chain of Responsibility) .這個(gè)關(guān)系到設(shè)計(jì)模式的職責(zé)鏈模式麦向。以多種不同的方法來(lái)解決一個(gè)問(wèn)題瘟裸。然后將他們鏈接在一起。當(dāng)一個(gè)請(qǐng)求到來(lái)時(shí)诵竭,遍歷這個(gè)鏈话告,直到鏈中的某個(gè)解決方案能夠處理該請(qǐng)求。

  8. 使用enum的狀態(tài)機(jī)

  9. 使用enum多路分發(fā)

作者:rhino

鏈接:www.cnblogs.com/happyPawpaw/archive/2013/04/09/3009553.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末卵慰,一起剝皮案震驚了整個(gè)濱河市沙郭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌裳朋,老刑警劉巖病线,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異鲤嫡,居然都是意外死亡送挑,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門暖眼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)惕耕,“玉大人,你說(shuō)我怎么就攤上這事罢荡∩耐唬” “怎么了?”我有些...
    開封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵区赵,是天一觀的道長(zhǎng)惭缰。 經(jīng)常有香客問(wèn)我,道長(zhǎng)笼才,這世上最難降的妖魔是什么漱受? 我笑而不...
    開封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上昂羡,老公的妹妹穿的比我還像新娘絮记。我一直安慰自己,他們只是感情好虐先,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開白布怨愤。 她就那樣靜靜地躺著,像睡著了一般蛹批。 火紅的嫁衣襯著肌膚如雪撰洗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天腐芍,我揣著相機(jī)與錄音差导,去河邊找鬼。 笑死猪勇,一個(gè)胖子當(dāng)著我的面吹牛设褐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播泣刹,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼助析,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了项玛?” 一聲冷哼從身側(cè)響起貌笨,我...
    開封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎襟沮,沒(méi)想到半個(gè)月后锥惋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡开伏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年膀跌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片固灵。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡捅伤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出巫玻,到底是詐尸還是另有隱情丛忆,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布仍秤,位于F島的核電站熄诡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏诗力。R本人自食惡果不足惜凰浮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧袜茧,春花似錦菜拓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至递递,卻和暖如春喷橙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背登舞。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留悬荣,地道東北人菠秒。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像氯迂,于是被迫代替她去往敵國(guó)和親践叠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容