欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Java中的枚舉(一)

系統 1841 0

在實際編程中,往往存在著這樣的“數據集”,它們的數值在程序中是穩定的,而且“數據集”中的元素是有限的。例如星期一到星期日七個數據元素組成了一周的“數據集”,春夏秋冬四個數據元素組成了四季的“數據集”。在 Java 中想表示這種數據集最容易想到的寫法可能是這樣,我們以表示一周五天的工作日來舉例:

Java 代碼

public class WeekDay {

public static final int MONDAY = 1;

public static final int TUESDAY = 2;

public static final int WENSDAY = 3;

public static final int THURSDAY = 4;

public static final int FRIDAY = 5;

}


現在,你的類就可以使用像 WeekDay.TUESDAY 這樣的常量了。但是這里隱藏著一些問題,這些常量是 Java int 類型的常量,這意味著該方法可以接受任何 int 類型的值,即使它和 WeekDay 中定義的所有日期都對應不上。因此,您需要檢測上界和下界,在出現無效值的時候,可能還要拋出一個 IllegalArgumentException 。而且,如果后來又添加另外一個日期(例如 WeekDay.SATURDAY ),那么必須改變所有代碼中的上界,才能接受這個新值。 換句話說,在使用這類帶有整型常量的類時,這個方案也許可行,但并不是非常有效。

Joshua Bloch 老大這時站了出來,在他的著作《 Effective Java 》中提出了在這樣場景下的一種非常好的模式—— Type-safe enumeration pattern 。這個模式簡而言之就是給這樣的常量類一個私有的構造方法,然后聲明一些 public static final 的同類型的變量暴露給使用者,例如:

Java 代碼

public class WeekDay {

public static final WeekDay MONDAY = new WeekDay(1);

public static final WeekDay TUESDAY = new WeekDay(2);

public static final WeekDay WENSDAY = new WeekDay(3);

public static final WeekDay THURSDAY = new WeekDay(4);

public static final WeekDay FRIDAY = new WeekDay(5);

public int getValue(){

return value;

}

private int value;

private WeekDay(int i){

this.value = i;

}

//other methods...

}

這樣做的好處是你的程序現在接受的不是 int 類型的數據了,而是 WeekDay 的一個預定義好的 static final 的實例( WeekDay.TUESDAY等 ),例如:

Java 代碼

public void setWeekDay(WeekDay weekDay){...}

而這樣做也避免了可以隨意向方法中傳遞一個不合法的 int 型數值(例如 -1 )而造成程序錯誤。同時,它還會帶來其他的一些好處:由于這些枚舉的對象都是一些類的實例,所以在里面放一些需要的屬性來存放數據;又由于他們都是單例的,你可以使用 equals 方法或是 == 符號來比較它們。

Joshua Bloch大大提出的枚舉模式,很好用但是好麻煩啊。如果你用過C/C++或是Pascal這樣的語言的話一定會對它們的枚舉類型有印象,例如在C/C++中我們可以這樣定義:

C/C++ 代碼

enum weekday {

MONDAY,

TUESDAY,

WENSDAY,

THURSDAY,

FRIDAY

};


然后在程序中就可以用 MONDAY 、 TUESDAY 這些變量了。這樣多方便,但是 Java 1.4 以前的版本并沒有提供枚舉類型的支持,所以如果你是用 JDK 1.4 開發程序的話就只能像 Joshua Bloch 老大那樣寫了。從 Java 5.0 (代號為 Tiger )開始,這種情況改變了, Java 從語言層面支持了枚舉類型。

枚舉是Tiger的一個很重要的新特性,它是一種新的類型,允許用常量來表示特定的數據片斷,而且全部都以類型安全的形式來表示,它使用“enum”關鍵字來定義。

我們先來寫一個簡單的枚舉類型的定義:

Java 代碼

public enum WeekDay{

MONDAY, TUESDAY, WENSDAY, THURSDAY, FRIDAY; // 最后這個“ ; ”可寫可不寫。

}

這和類、接口的定義很相像嘛!Tiger中的枚舉類型就是一種使用特殊語法“enum”定義的類。所有的枚舉類型是java.lang.Enum的子類。這是Tiger中新引入的一個類,它本身并不是枚舉類型,但它定義了所有枚舉類型所共有的行為,如下表:

Java中的枚舉(一)

注意: 雖然所有的枚舉類型都繼承自java.lang.Enum,但是你不能繞過關鍵字“enum”而使用直接繼承Enum的方式來定義枚舉類型。編譯器會提示錯誤來阻止你這么做。

WeekDay中定義的五個枚舉常量之間使用“,”分割開來。這些常量默認都是“public static final”的,所以你就不必再為它們加上“public static final”修飾(編譯器會提示出錯),這也是為什么枚舉常量采用大寫字母來命名的原因。而且每一個常量都是枚舉類型WeekDay的一個實例。你可以通過類似“WeekDay.MONDAY”這種格式來獲取到WeekDay中定義的枚舉常量,也可以采用類似“WeekDay oneDay = WeekDay.MONDAY”的方式為枚舉類型變量賦值(你不能給枚舉類型變量分配除了枚舉常量和null以外的值,編譯器會提示出錯)。

作為枚舉類型實例的枚舉常量是如何初始化的呢?其實答案很簡單,這些枚舉常量都是通過Enum中定義的構造函數進行初始化的。

Java 代碼

//java.lang.Enum 中定義的構造函數,

// 兩個參數分別是定義的枚舉常量名稱以及它所在的次序。

protected Enum(String name, int ordinal) {

this.name = name;

this.ordinal = ordinal;

}

在初始化的過程中,枚舉常量的次序是按照聲明的順序安排的。第一個枚舉常量的次序是0,依此累加。

枚舉類型除了擁有Enum提供的方法以外,還存在著兩個隱藏著的與具體枚舉類型相關的靜態方法——values()和valueOf(String arg0)。方法values()可以獲得包含所有枚舉常量的數組;方法valueOf是java.lang.Enum中方法valueOf的簡化版本,你可以通過它,根據傳遞的名稱來得到當前枚舉類型中匹配的枚舉常量。

我們來看一個枚舉類型使用的小例子。需求中要求可以對指定的日期進行相應的信息輸出。對于這么簡單的需求,這里就使用枚舉類型來進行處理。前面我們已經定義好了包含有五個工作日的枚舉類型。下面的代碼則是進行輸出的方法:

Java 代碼

/**

* 根據日期的不同輸出相應的日期信息。

* @param weekDay 代表不同日期的枚舉常量

*/

public void printWeekDay(WeekDay weekDay){

switch(weekDay){

case MONDAY:

System.out.println(“Today is Monday!”);

break;

case TUESDAY:

System.out.println(“Today is Tuesday!”);

break;

case WENSDAY:

System.out.println(“Today is Wensday!”);

break;

case THURSDAY:

System.out.println(“Today is hursday!”);

break;
case FRIDAY:

System.out.println(“Today is Friday!”);

break;

default:
throw new AssertionError("Unexpected value: " + weekDay);

}

}

在Tiger以前,switch操作僅能對int、short、char和byte進行操作。而在Tiger中,switch增加了對枚舉類型的支持,因為枚舉類型僅含有有限個可以使用整數代替的枚舉常量,這太適合使用switch語句了!就像上面代碼中那樣,你在swtich表達式中放置枚舉類型變量,就可以在case標示中直接使用枚舉類型中的枚舉常量了。

注意: case標示的寫法中沒有枚舉類型前綴,這意味著不能將代碼寫成 case Operation. PLUS,只需將其寫成 case PLUS即可。否則,編譯器會提示出錯信息。

像上面的例子一樣,雖然你已經在case標示中窮盡了某個枚舉類型中的所有枚舉常量,但還是建議你在最后加上default標示(就像上面代碼示意的那樣)。因為萬一為枚舉類型添加一個新的枚舉常量,而忘了在switch中添加相應的處理,是很難發現錯誤的。

為了更好的支持枚舉類型,java.util中添加了兩個新類:EnumMap和EnumSet。使用它們可以更高效的操作枚舉類型。下面我一一介紹給你:

EnumMap 是專門為枚舉類型量身定做的Map實現。雖然使用其它的Map實現(如HashMap)也能完成枚舉類型實例到值得映射,但是使用EnumMap會更加高效:它只能接收同一枚舉類型的實例作為鍵值,并且由于枚舉類型實例的數量相對固定并且有限,所以EnumMap使用數組來存放與枚舉類型對應的值。這使得EnumMap的效率非常高。

提示: EnumMap在內部使用枚舉類型的ordinal()得到當前實例的聲明次序,并使用這個次序維護枚舉類型實例對應值在數組的位置。

下面是使用EnumMap的一個代碼示例。枚舉類型DataBaseType里存放了現在支持的所有數據庫類型。針對不同的數據庫,一些數據庫相關的方法需要返回不一樣的值,示例中getURL就是一個。

Java 代碼

// 現支持的數據庫類型枚舉類型定義

public enum DataBaseType{

MYSQL,ORACLE,DB2,SQLSERVER

}

// 某類中定義的獲取數據庫 URL 的方法以及 EnumMap 的聲明。

……

private EnumMap<DataBaseType ,String> urls =

new EnumMap<DataBaseType ,String>(DataBaseType.class);

public DataBaseInfo(){

urls.put(DataBaseType.DB2,"jdbc:db2://localhost:5000/sample");

urls.put(DataBaseType.MYSQL,"jdbc:mysql://localhost/mydb");

urls.put(DataBaseType.ORACLE,"jdbc:oracle:thin:@localhost:1521:sample");

urls.put(DataBaseType.SQLSERVER,"jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb");

}

/**

* 根據不同的數據庫類型,返回對應的 URL

* @param type DataBaseType 枚舉類新實例

* @return

*/

public String getURL(DataBaseType type){

return this.urls.get(type);

}

在實際使用中,EnumMap對象urls往往是由外部負責整個應用初始化的代碼來填充的。這里為了演示方便,類自己做了內容填充。

像例子中那樣,使用EnumMap可以很方便的為枚舉類型在不同的環境中綁定到不同的值上。如:例子中getURL綁定到URL上,在其它的代碼中可能又被綁定到數據庫驅動上去。

EnumSet 是枚舉類型的高性能Set實現。它要求放入它的枚舉常量必須屬于同一枚舉類型。EnumSet提供了許多工廠方法以便于初始化,見下表:

Java中的枚舉(一)

EnumSet作為Set接口實現,它支持對包含的枚舉常量的遍歷:

Java 代碼

for(Operation op : EnumSet.range(Operation.PLUS , Operation.MULTIPLY)) {

doSomeThing(op);

}

Java中的枚舉(一)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。?!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 偷拍第一页 | 日本一道在线 | 一道本视频| 久久精品免费视频观看 | 国产精品高潮呻吟久久aⅴ码 | 在线天堂中文在线资源网 | 久青青| 亚洲第一a亚洲 | 仇爱电视剧泰剧在线观看免费播放 | 日本三级欧美三级 | 天天视频网站 | 欧美精品videosex极品 | 日韩欧美亚洲一区 | 91视频这里只有精品 | 亚洲欧美国产日产综合不卡 | 精品久久久久久一区二区 | 性高湖久久久久久久久aaaaa | 国产精品久久久久久久久软件 | 国产极品福利视频在线观看 | 日本色图视频 | 男女全黄做爰视频免费看 | 久久亚洲国产精品五月天婷 | 日本大人吃奶视频xxxx | 欧美成人精品不卡视频在线观看 | 国产高清精品一区二区三区 | 毛片卡一卡二 | 99国产精品2018视频全部 | gogo全球大胆高清人露出91 | 日本精品一二三区 | 久久婷婷综合五月一区二区 | 欧美日韩亚洲国产 | 夜操| 国产在线视频91 | 国产二区三区 | 奇米影 | 日韩精品免费观看 | 欧美久久久久久 | 日韩色区| 波多野结衣中文在线播放 | 欧美一区二区在线播放 | 黄色大片在线播放 |