Java5 前常量類使用設(shè)計(jì)的缺陷
? Java5出現(xiàn)之前垄琐,如果我們要通過Class 來表示一類常量或某幾類常量疏尿,通常會(huì)采用下面的代碼來實(shí)現(xiàn)(這里用顏色來舉例):比如在實(shí)現(xiàn)一個(gè)簡單的畫圖軟件時(shí)晚岭,可能會(huì)涉及到畫筆的很多顏色值君仆,此時(shí)我們會(huì)定義一下常量值來代表某個(gè)顏色值:
public class ColorEntity {
public static final int BLACK=1;
public static final int WHITE=2;
public static final int YELLOW=3;
public static final int BLUE=4;
public static final int RED=5;
private int type;
private int id;
}
此時(shí)使用該類時(shí) 就會(huì)出現(xiàn)一些問題:
public static void main(String[] args) {
ColorEntity colorEntity=new ColorEntity();
colorEntity.setId(1);
colorEntity.setType(1);//1代表神馬??喇辽?
}
這里的type=1 到底代表什么意思牡昆,雖然開發(fā)人員理解1對(duì)應(yīng)BLACK,但會(huì)造成代碼可讀性差,不易于后期維護(hù)掂器,因?yàn)檫@里的1在1.0版代表的為BLACK沒錯(cuò)亚皂,但可能到2.0版后1就不一定代表BLACK,或許是WHITE国瓮、GREEN灭必、RED...
當(dāng)然實(shí)例化ColorEntity對(duì)象時(shí)這里的代碼可以有以下改進(jìn):
ColorEntity colorEntity=new ColorEntity();
colorEntity.setId(1);
// 不是每個(gè)程序員都能夠做到的 大量離散的常量寫在當(dāng)前類中也不易于后期維護(hù)
colorEntity.setType(ColorEntity.BLACK);
此時(shí)不是每個(gè)程序員都能夠做到的 大量離散的常量寫在當(dāng)前類中也不易于后期維護(hù)!!!
? 枚舉就是為了這樣的問題而誕生的狞谱。Java5引入了枚舉特性,存放在 java.lang 包中 禁漓,枚舉是一個(gè)特定類型的類跟衅。所有枚舉都是Java中的新類java.lang.Enum的隱式子類, 此類不能手工進(jìn)行子類定義播歼。
枚舉定義
? 創(chuàng)建枚舉類型要使用 enum 關(guān)鍵字伶跷,隱含了所創(chuàng)建的類型都是 java.lang.Enum 類的子類(java.lang.Enum 是一個(gè)抽象類)。枚舉類型符合通用模式class Enum<E extends Enum<E>>秘狞,而E表示枚舉類型的名稱叭莫。枚舉類型的每一個(gè)值都將映射到protected Enum(String name, int ordinal) 構(gòu)造函數(shù)中,在這里谒撼,每個(gè)值的名稱都被轉(zhuǎn)換成一個(gè)字符串食寡,并且序數(shù)設(shè)置表示了此設(shè)置被創(chuàng)建的順序。
定義顏色枚舉類ColorEnum_1:
public enum ColorEnum_1{
BLACK,WHITE,YELLOW,BLUE,RED;
}
此時(shí) Enum類 構(gòu)造方法相當(dāng)于被調(diào)用5次廓潜。
枚舉遍歷與switch判斷
/**
* 顏色枚舉類遍歷
*/
public static void test02(){
for(ColorEnum_1 ColorEnum_1:ColorEnum_1.values()){
System.out.println(ColorEnum_1.name() +","+ ColorEnum_1.ordinal());
}
}
遍歷結(jié)果如下:
枚舉類同樣支持switch 判斷
ColorEnum_1 ColorEnum_1 = ColorEnum_1.BLACK;
switch (ColorEnum_1){
case RED:
System.out.println("紅色畫筆");
break;
case BLACK:
System.out.println("黑色畫筆");
break;
case BLUE:
System.out.println("藍(lán)色畫筆");
break;
default:
System.out.println("默認(rèn)顏色");
break;
}
結(jié)果如下:
枚舉常用方法
int compareTo(E o) 比較此枚舉與指定對(duì)象的順序抵皱。
Class<E> getDeclaringClass() 返回與此枚舉常量的枚舉類型相對(duì)應(yīng)的 Class 對(duì)象。
String name() 返回此枚舉常量的名稱辩蛋,在其枚舉聲明中對(duì)其進(jìn)行聲明呻畸。
int ordinal() 返回枚舉常量的序數(shù)(它在枚舉聲明中的位置,其中初始常量序數(shù)為零)悼院。
String toString()返回枚舉常量的名稱伤为,它包含在聲明中。
static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) 返回帶指定名稱的指定枚舉類型的枚舉常量据途。
代碼示例:
//compareTo(E o) 比較兩個(gè)枚舉類順序 返回順序差值
switch (ColorEnum_1.compareTo(ColorEnum_1.WHITE)) {
case -1:
System.out.println("Black 在 White 順序前");
break;
case 1:
System.out.println("Black 在 White 順序后");
break;
default:
System.out.println("Black 與 White 在同一位置");
break;
}
//getDeclaringClass() 枚舉類相對(duì)應(yīng)class 名稱
System.out.println("getDeclaringClass(): " + ColorEnum_1.getDeclaringClass().getName());
//name() 和 toString()
System.out.println("name(): " + ColorEnum_1.name());
System.out.println("toString(): " + ColorEnum_1.toString());
//ordinal()绞愚, 返回值是從 0 開始
System.out.println("ordinal(): " + ColorEnum_1.ordinal());
結(jié)果如下:
枚舉實(shí)現(xiàn)顏色常量類功能-自定義屬性與方法
- 枚舉類定義
public enum ColorEnum_2 {
BLACK(1),WHITE(2),YELLOW(3),BLUE(4),RED(5);
private int type;
ColorEnum_2(int type) {
this.type = type;
}
public int getType() {
return type;
}
}
- 使用枚舉
// 使用枚舉給顏色類型賦值
ColorEntity colorEntity = new ColorEntity();
colorEntity.setId(1);
// 通過枚舉執(zhí)行畫筆顏色值 代碼清晰 簡單!S币健位衩!
colorEntity.setType(ColorEnum_2.BLACK.getType());
枚舉原理分析
Enum 的語法結(jié)構(gòu)盡管和 class 的語法不一樣,但是經(jīng)過編譯器編譯之后產(chǎn)生的是一個(gè)class文件熔萧。該class文件經(jīng)過反編譯可以看到實(shí)際上是生成了一個(gè)類糖驴,該類繼承了java.lang.Enum<E>。 在ColorEnum_2 類class所在目錄執(zhí)行javap -c ColorEnum_2 命令可以看到Enum 經(jīng)過編譯之后就是我們熟悉的class類佛致,到這里基本就真相大白啦贮缕!
public final class com.lzj.ColorEnum_2 extends java.lang.Enum<com.lzj.ColorEnum_2> {
public static final com.lzj.ColorEnum_2 BLACK;
public static final com.lzj.ColorEnum_2 WHITE;
public static final com.lzj.ColorEnum_2 YELLOW;
public static final com.lzj.ColorEnum_2 BLUE;
public static final com.lzj.ColorEnum_2 RED;
...
}
所以,我們說enum 就是一個(gè) class,只不過 java 編譯器幫我們做了語法的解析和編譯而已俺榆。在開發(fā)中感昼,通常用于表示諸如顏色、方式肋演、類別抑诸、狀態(tài)等等數(shù)目有限烂琴、形式離散、表達(dá)又極為明確的量蜕乡,應(yīng)當(dāng)盡量舍棄常量表示的做法奸绷,而將枚舉作為首要的選擇。