天天看點

java enum(枚舉)使用詳解 + 總結 - ido - 部落格園

    enum 的全稱為 enumeration, 是 JDK 1.5  中引入的新特性,存放在 java.lang 包中。

    下面是我在使用 enum 過程中的一些經驗和總結,主要包括如下内容:

1. 原始的接口定義常量

2. 文法(定義)

3. 周遊、switch 等常用操作

4. enum 對象的常用方法介紹

5. 給 enum 自定義屬性和方法

6. EnumSet,EnumMap 的應用

7. enum 的原理分析

8. 總結

原始的接口定義常量

public

interface

IConstants {

String MON =

"Mon"

;

String TUE =

"Tue"

;

String WED =

"Wed"

;

String THU =

"Thu"

;

String FRI =

"Fri"

;

String SAT =

"Sat"

;

String SUN =

"Sun"

;

}

文法(定義)

    建立枚舉類型要使用 enum 關鍵字,隐含了所建立的類型都是 java.lang.Enum 類的子類(java.lang.Enum 是一個抽象類)。枚舉類型符合通用模式 

Class Enum<E extends Enum<E>>

,而 

E

 表示枚舉類型的名稱。枚舉類型的每一個值都将映射到 

protected Enum(String name, int ordinal)

 構造函數中,在這裡,每個值的名稱都被轉換成一個字元串,并且序數設定表示了此設定被建立的順序。

package

com.hmw.test;

public

enum

EnumTest {

MON, TUE, WED, THU, FRI, SAT, SUN;

}

這段代碼實際上調用了7次 Enum(String name, int ordinal):

new

Enum<EnumTest>(

"MON"

,

);

new

Enum<EnumTest>(

"TUE"

,

1

);

new

Enum<EnumTest>(

"WED"

,

2

);

... ...

周遊、switch 等常用操作

對enum進行周遊和switch的操作示例代碼:

public

class

Test {

public

static

void

main(String[] args) {

for

(EnumTest e : EnumTest.values()) {

System.out.println(e.toString());

}

System.out.println(

"----------------我是分隔線------------------"

);

EnumTest test = EnumTest.TUE;

switch

(test) {

case

MON:

System.out.println(

"今天是星期一"

);

break

;

case

TUE:

System.out.println(

"今天是星期二"

);

break

;

// ... ...

default

:

System.out.println(test);

break

;

}

}

}

輸出結果:

MON

TUE

WED

THU

FRI

SAT

SUN

----------------我是分隔線------------------

今天是星期二

enum 對象的常用方法介紹

int 

compareTo(E o)

          比較此枚舉與指定對象的順序。

Class<E> 

getDeclaringClass()

          傳回與此枚舉常量的枚舉類型相對應的 Class 對象。

String 

name()

          傳回此枚舉常量的名稱,在其枚舉聲明中對其進行聲明。

int 

ordinal()

          傳回枚舉常量的序數(它在枚舉聲明中的位置,其中初始常量序數為零)。

String 

toString()

          傳回枚舉常量的名稱,它包含在聲明中。

static 

<T extends Enum<T>> T 

valueOf(Class<T> enumType, String name)

          傳回帶指定名稱的指定枚舉類型的枚舉常量。

public

class

Test {

public

static

void

main(String[] args) {

EnumTest test = EnumTest.TUE;

//compareTo(E o)

switch

(test.compareTo(EnumTest.MON)) {

case

-

1

:

System.out.println(

"TUE 在 MON 之前"

);

break

;

case

1

:

System.out.println(

"TUE 在 MON 之後"

);

break

;

default

:

System.out.println(

"TUE 與 MON 在同一位置"

);

break

;

}

//getDeclaringClass()

System.out.println(

"getDeclaringClass(): "

+ test.getDeclaringClass().getName());

//name() 和  toString()

System.out.println(

"name(): "

+ test.name());

System.out.println(

"toString(): "

+ test.toString());

//ordinal(), 傳回值是從 0 開始

System.out.println(

"ordinal(): "

+ test.ordinal());

}

}

輸出結果:

TUE 在 MON 之後

getDeclaringClass(): com.hmw.test.EnumTest

name(): TUE

toString(): TUE

ordinal(): 1

給 enum 自定義屬性和方法

給 enum 對象加一下 value 的屬性和 getValue() 的方法:

package

com.hmw.test;

public

enum

EnumTest {

MON(

1

), TUE(

2

), WED(

3

), THU(

4

), FRI(

5

), SAT(

6

) {

@Override

public

boolean

isRest() {

return

true

;

}

},

SUN(

) {

@Override

public

boolean

isRest() {

return

true

;

}

};

private

int

value;

private

EnumTest(

int

value) {

this

.value = value;

}

public

int

getValue() {

return

value;

}

public

boolean

isRest() {

return

false

;

}

}

public

class

Test {

public

static

void

main(String[] args) {

System.out.println(

"EnumTest.FRI 的 value = "

+ EnumTest.FRI.getValue());

}

}

輸出結果:

EnumTest.FRI 的 value = 5

EnumSet,EnumMap 的應用

public

class

Test {

public

static

void

main(String[] args) {

// EnumSet的使用

EnumSet<EnumTest> weekSet = EnumSet.allOf(EnumTest.

class

);

for

(EnumTest day : weekSet) {

System.out.println(day);

}

// EnumMap的使用

EnumMap<EnumTest, String> weekMap =

new

EnumMap(EnumTest.

class

);

weekMap.put(EnumTest.MON,

"星期一"

);

weekMap.put(EnumTest.TUE,

"星期二"

);

// ... ...

for

(Iterator<Entry<EnumTest, String>> iter = weekMap.entrySet().iterator(); iter.hasNext();) {

Entry<EnumTest, String> entry = iter.next();

System.out.println(entry.getKey().name() +

":"

+ entry.getValue());

}

}

}

原理分析

        enum 的文法結構盡管和 class 的文法不一樣,但是經過編譯器編譯之後産生的是一個class檔案。該class檔案經過反編譯可以看到實際上是生成了一個類,該類繼承了java.lang.Enum<E>。EnumTest 經過反編譯(javap com.hmw.test.EnumTest 指令)之後得到的内容如下:

public

class

com.hmw.test.EnumTest

extends

java.lang.Enum{

public

static

final

com.hmw.test.EnumTest MON;

public

static

final

com.hmw.test.EnumTest TUE;

public

static

final

com.hmw.test.EnumTest WED;

public

static

final

com.hmw.test.EnumTest THU;

public

static

final

com.hmw.test.EnumTest FRI;

public

static

final

com.hmw.test.EnumTest SAT;

public

static

final

com.hmw.test.EnumTest SUN;

static

{};

public

int

getValue();

public

boolean

isRest();

public

static

com.hmw.test.EnumTest[] values();

public

static

com.hmw.test.EnumTest valueOf(java.lang.String);

com.hmw.test.EnumTest(java.lang.String,

int

,

int

, com.hmw.test.EnumTest);

}

是以,實際上 enum 就是一個 class,隻不過 java 編譯器幫我們做了文法的解析和編譯而已。

總結

    可以把 enum 看成是一個普通的 class,它們都可以定義一些屬性和方法,不同之處是:enum 不能使用 extends 關鍵字繼承其他類,因為 enum 已經繼承了 java.lang.Enum(java是單一繼承)。