當前位置:成語大全網 - 書法字典 - java中的enum是什麽意思?

java中的enum是什麽意思?

枚舉類型簡介

枚舉類型很早就出現在編程語言中,它們用於將壹組相似的值包含到壹個類型中。該枚舉類型的名稱將被定義為唯壹的類型描述符,這類似於常量的定義。但是,與常量類型相比,枚舉類型可以為聲明的變量提供更大範圍的值。

例如,如果妳想給彩虹塗上七種顏色,妳可以通過在Java程序中定義常量來實現。

清單1。常數定義

公?靜電?班級?RainbowColor?{?

//?恒定定義七種顏色:紅、橙、黃、綠、青、藍、紫。

公共?靜電?決賽?int?紅色?=?0;?

公共?靜電?決賽?int?橙色?=?1;?

公共?靜電?決賽?int?黃色?=?2;?

公共?靜電?決賽?int?綠色?=?3;?

公共?靜電?決賽?int?青色?=?4;?

公共?靜電?決賽?int?藍色?=?5;?

公共?靜電?決賽?int?紫色?=?6;?

}使用時,可以在程序中直接引用這些常量。然而,這種方式仍然存在壹些問題。

類型不安全。

因為顏色常量對應的值是壹個整數,所以在程序執行過程中很有可能會將任意壹個整數值傳入顏色變量,從而導致錯誤。

沒有命名空間。

由於顏色常量只是類的屬性,所以在使用它們時,必須通過類來訪問它們。

壹致性差

因為整數枚舉是壹個編譯時常量,所以編譯過程完成後,客戶端和服務器引用的所有地方都會直接把整數值寫入。這樣,當妳修改舊的枚舉整數值或者添加新的枚舉值時,所有引用的本地代碼都需要重新編譯,否則運行時會出錯。

類型不確定性

由於顏色枚舉值只是無意義的整數值,如果在運行時調試,會發現日誌中有很多幻數,但除了程序員自己,其他人很難理解其中的奧妙。

如何定義枚舉類型

為了改善Java語言在這方面的不足,彌補缺陷,SDK 5.0版本發布時,在語言層面增加了枚舉類型。枚舉類型的定義也很簡單,使用enum關鍵字和名字和大括號括起來的枚舉值體就可以了。例如,上面提到的彩虹顏色可以用新的枚舉方式重新定義:

enum?RainbowColor?{?紅色?橘子,?黃色的?綠色?青色,?藍色的?紫色?}從上面的定義形式來看,似乎Java中的枚舉類型很簡單,但實際上Java語言規範賦予了枚舉類型非常強大的功能。它不僅簡單地將整數值轉換為對象,還將枚舉類型定義轉換為功能齊全的類定義。類型定義的這種擴展允許開發人員向枚舉類型添加任何方法和屬性,並且還可以實現任何接口。此外,Java平臺還為Enum類型提供了高質量的實現,比如Comparable和Serializable接口的默認實現,這樣開發人員壹般不用關心這些細節。

回到本文的主題,枚舉類型的引入能給我們的開發帶來什麽好處?最直接的好處之壹就是擴大了switch語句的使用範圍。在5.0之前,Java中switch的值只能是簡單類型,比如int,byte,short,char。枚舉類型後,可以使用對象。這樣,程序的控制選擇變得更加方便,參見下面的例子:

清單2。定義枚舉類型

//?定義壹周七天的枚舉類型。

公共?enum?WeekDayEnum?{?媽媽?星期二?星期三?周四?Fri?Sat,?孫?}?

//?閱讀當天的信息

WeekDayEnum?今天嗎?=?readToday();?

//?根據日期選擇活動。

切換(今天)?{?

周壹:?做什麽?東西;?打破;?

周二:?做什麽?東西;?打破;?

周三:?做什麽?東西;?打破;?

周四:?做什麽?東西;?打破;?

Fri:?做什麽?東西;?打破;?

Sat:?玩?體育?遊戲;?打破;?

孫:?有嗎?答?休息;?打破;?

對於這些枚舉的日期,JVM將在運行時構造壹個簡單的壹對壹對應的對象實例。這些對象都有唯壹的標識,類似於整數值,switch語句據此執行跳轉。

如何自定義枚舉類型

除了上面最常見的枚舉定義,如果需要給枚舉類型添加壹些復雜的函數,也可以通過類似class的定義自定義枚舉。例如,要向枚舉類型添加屬性,可以按如下方式定義它們:

清單3。自定義枚舉類型

//?定義?RSS(真的?簡單?辛迪加)?種子的枚舉類型

公共?enum?新聞供稿?{?

//?雅虎頭條?RSS?種子

YAHOO _ TOP _ STORIES("/RSS/topstories "),?

//CBS?頭條?RSS?種子

CBS_TOP_STORIES("/CBSNewsMain?format=xml "),?

//?洛杉磯時報頭條?RSS?種子

LATIMES _ TOP _ STORIES("/LATIMES/news?format = XML ");?

//?枚舉對象?RSS?地址屬性

私人?字符串?rss _ url?

//?枚舉對象構造函數

私人?NewsRSSFeedEnum(字符串?rss)?{?

this.rss_url?=?rss?

}?

//?枚舉對象獲取?RSS?地址方法

公共?字符串?getRssURL()?{?

回歸?this.rss _ url?

}?

}上面頭條新聞的枚舉類型,增加了壹個RSS地址的屬性,記錄頭條新聞的訪問地址。同時RSS訪問地址的值需要對外傳入,所以需要定義壹個構造函數來初始化這個屬性。此外,您需要提供讀取RSS地址的方法。

如何避免誤用枚舉

但是,使用Enum時有幾點需要註意:

枚舉類型不支持public和protected修飾符的構造函數,因此構造函數必須是私有的或友好的。因此,枚舉對象不能通過在程序中直接調用其構造函數來初始化。

定義枚舉類型時,如果是簡單類型,那麽最後壹個枚舉值後面不需要跟任何符號;但是如果有自定義方法,那麽最後壹個枚舉值和下面的代碼應該使用分號“;”分開,沒有逗號或空格。

因為枚舉類型的值實際上是通過在運行時構造對象來表示的,所以在集群環境中,每個虛擬機都會構造壹個同義的枚舉對象。所以需要註意的是,如果直接使用等號(' = = ')運算符,這些看似相同的枚舉值壹定是不相等的,因為它們不是同壹個對象實例。

請看下面的例子:

清單4。避免誤用枚舉示例

//?定義壹周七天的枚舉類型。

包裹?示例.枚舉.代碼;?

公共?enum?WeekDayEnum?{?

Mon(1),?周二(2),?Wed(3),?Thu(4),?Fri(5),?Sat(6),?孫(7);?

私人?int?指數;?

WeekDayEnum(int?idx)?{?

this.index?=?idx?

}?

公共?int?getIndex()?{?

回歸?指數;?

}?

}//?客戶端程序通過網絡向服務器發送枚舉值。

包裹?示例.枚舉.代碼;?

進口?Java . io . io exception;?

進口?Java . io . object output stream;?

進口?Java . io . output stream;?

進口?Java . net . inetsocketaddress;?

進口?Java . net . socket;?

進口?Java . net . unknown host exception;?

公共?班級?枚舉客戶端?{?

公共?靜電?作廢?主(字符串...?args)?摔投?未知主機異常,?IOException?{?

插座?插座?=?新的?socket();?

//?建立與服務器的連接。

socket.connect(新?InetSocketAddress(" 127 . 0 . 0 . 1 ",8999));?

//?從連接中獲取輸出流

OutputStream?os?=?socket . get output stream();?

ObjectOutputStream?oos?=?新的?ObjectOutputStream(OS);?

//?將Friday的枚舉值傳遞給服務器。

oos.writeObject(WeekDayEnum。Fri);?

OOS . close();?

OS . close();?

socket . close();?

}?

}?

//?壹個服務器端程序,將從客戶端接收的枚舉值應用於邏輯處理。

包裹?示例.枚舉.代碼;?

進口?Java . io . *;?

進口?Java . net . server socket;?

進口?Java . net . socket;?

公共?班級?EnumerationServer?{?

公共?靜電?作廢?主(字符串...?args)?摔投?IOException,?ClassNotFoundException?{?

ServerSocket?服務器?=?新的?server socket(8999);?

//?建立服務器端網絡連接攔截

插座?插座?=?server . accept();?

//?從連接中獲取輸入流。

InputStream?是嗎?=?socket . getinputstream();?

ObjectInputStream?ois?=?新的?ObjectInputStream(是);?

//?讀取客戶端傳遞的枚舉值。

WeekDayEnum?日?=?(WeekDayEnum)?ois . read object();?

//?通過值比較來比較枚舉對象。

如果?(日?==?工作日枚舉。Fri)?{?

System.out.println("client?星期五?enum?價值?是嗎?壹樣?作為?服務器的”);?

}?不然呢?如果?(day.equals(WeekDayEnum。Fri)?{?

System.out.println("client?星期五?enum?價值?是嗎?平等?去哪?服務器的”);?

}?不然呢?{?

System.out.println("client?星期五?enum?價值?是嗎?不是嗎?壹樣?作為?服務器的”);?

}?

//?使用?切換?方法來比較枚舉對象。

切換?(天)?{?

案子?周壹:?

System.out.println("Do?星期壹?工作”);?

打破;?

案子?周二:?

System.out.println("Do?星期二?工作”);?

打破;?

案子?周三:?

System.out.println("Do?星期三?工作”);?

打破;?

案子?周四:?

System.out.println("Do?周四?工作”);?

打破;?

案子?Fri:?

System.out.println("Do?星期五?工作”);?

打破;?

案子?Sat:?

System.out.println("Do?周六?工作”);?

打破;?

案子?孫:?

System.out.println("Do?周日嗎?工作”);?

打破;?

默認:?

System.out.println("I?不要?知道嗎?哪個?是嗎?天”);?

打破;?

}?

ois . close();?

is . close();?

socket . close();?

}?

}打印結果如下:

客戶端星期五枚舉值與服務器相同

周五工作

通過程序執行的結果可以發現,在分布式的情況下,客戶端和服務器端的虛擬機上都生成了壹個枚舉對象。即使Fri枚舉值看起來壹樣,如果用等號' = = '來比較,也會有不相等。switch語句通過equal方法比較枚舉對象的值,因此當您的枚舉對象很復雜時,您需要小心與覆蓋相關的方法,以防止值比較中的錯誤。

枚舉相關工具類

在JDK5.0中,在添加Enum類的同時,還添加了EnumSet和EnumMap兩個工具類,這兩個工具類都放在java.util包中。EnumSet是枚舉類型的高性能Set接口實現。EnumSet中加載的所有枚舉對象必須是同壹類型,並且是通過位向量實現的,也就是通過壹個長數字實現的。EnumSet支持遍歷枚舉類型的所有值。回到上面的日期枚舉示例:

enum?WeekDayEnum?{?媽媽?星期二?星期三?周四?Fri?Sat,?孫?}您可以壹周叠代七天,EnumSet類提供了壹個靜態方法範圍,使叠代易於完成:

for(WeekDayEnum?日?:?EnumSet.range(WeekDayEnum。媽媽?工作日枚舉。Fri)?{?

System.out.println(日);?

}打印結果如下:

蒙?

周二?

婚禮?

Thu?

FriEnumSet還提供了許多類型的獲取子集的安全方法,這使您可以輕松地獲取子集:

EnumSet & ltWeekDayEnum & gt?子集?=?EnumSet.of(WeekDayEnum。媽媽?工作日枚舉。wed);?

為了什麽?(WeekDayEnum?日?:?子集)?{?

System.out.println(日);

}打印結果如下:

蒙?

Wed類似於EnumSet,EnumMap也是壹個高性能的Map接口實現,用來管理以枚舉類型為鍵的映射表,在內部通過數組實現。EnumMap結合了豐富而安全的地圖界面和對陣列的快速訪問。如果要將枚舉類型映射到值,應該使用EnumMap。請看下面的例子:

清單5。EnumMap示例

//?定義壹個?EnumMap?對象,映射表主鍵是日期枚舉類型,值是顏色枚舉類型。

私人?靜電?地圖& ltWeekDayEnum,?RainbowColor & gt?圖式?=?

新的?EnumMap & ltWeekDayEnum,?RainbowColor & gt(weekdayenum . class);?

靜態{?

//?用某種顏色的彩虹繪制壹周中的每壹天。

為了什麽?(int?我?=?0;?我?& lt?WeekDayEnum.values()。長度;?i++)?{?

schema . put(weekday enum . values()[I],?rainbow color . values()[I]);?

}?

}?

System.out.println("什麽?是嗎?那個?幸運嗎?顏色?今天?”);?

System.out.println("是嗎?"?+?schema.get(WeekDayEnum。sat));當妳問星期六的幸運顏色時,妳會得到藍色:

清單6。運行結果

今天的幸運色是什麽?

它是藍色的

結束語

Enum類型給JAVA編程帶來了極大的便利,使得程序的控制更加容易,不容易出錯。所以當妳需要控制程序流程的時候,可以多想想是否可以用enum來實現。