Java基礎--列舉
本文主要講解Java列舉的使用以及與使用常量的區別,由於本人水平有限,寫作之前參考了幾位大神的文章,對列舉的應用有了更深的理解。特記錄下本文章,以供自己翻閱。
參考文章地址:
https://blog.csdn.net/zyhlwzy/article/details/79045066
https://blog.csdn.net/myzksky/article/details/81150199
https://blog.csdn.net/yin_pisces/article/details/52050427
一、版本歷史
列舉(Enum)是JDK1.5版本新增的特性,1.5版本新增的特性還有泛型,For-each。JDK 1.6版本之後,switch case語句支援列舉型別的判斷。
二、什麼是列舉
列舉(Enum)是一種特殊的資料型別,它即是一種類(class)型別又比這個型別多了些特殊的約束。這些約束使其類更加的安全,方便使用。
1.建立一個列舉類
enum UserType{
USER("USER","內部使用者",1),CUSTOMER("CUSTOMER","消費者",2),PARTNER("PARTNER","合作商",3);
private String userType;
private String typeName;
private Integer typeIndex;
private UserType(String userType,String typeName,Integer typeIndex){
this.userType=userType;
this.typeName=typeName;
this.typeIndex=typeIndex;
}
// get set 方法
@Override
public String toString() {
return this.userType+"_"+this.typeName;
};
System.out.println(UserType.USER.getTypeName()); // 內部使用者
System.out.println(UserType.USER); // USER 沒有複寫toString()方法
System.out.println(UserType.USER); // USER_內部使用者 複寫了toString()方法
列舉是一個特殊的類,它也有例項欄位、構造器和方法。預設無參構造器不能夠被宣告並且所有的構造器必須被private修飾,列舉例項用","
隔開,序列的最後用";"
結束
建立一個列舉類要使用關鍵字 enum
,隱藏的含義為該列舉類自動繼承了java.lang.Enum<T>
(抽象泛型類),只能實現介面而不能繼承,Java編譯器在編譯時做了這個轉換
enum UserType extends Eunum<UserType>{
// something
};
實際上每一個繼承自Enum<T>
的列舉允許定義泛型類、介面和方法,通過這種方式可以讓列舉型別的例項引數化或者型別引數化。比如:
public<T extends Enum< ? >> void performAction(final T instance) {
// Perform some action here
}
在上面的宣告中,型別T被約定為任意列舉型別的例項並且Java編譯器將會對其做驗證
2.實現介面
interface IsUser{
boolean ifUser();
}
兩種實現方式:
①
enum UserType implements IsUser{
USER("USER",true),CUSTOMER("CUSTOMER",true)
private String userType;
private boolean isUser;
UserType(String userType,boolean isUser){
this.userType=userType;
this.isUser=isUser;
}
boolean ifUser(){
return this.isUser;
}
}
System.out.println(UserType.USER.isUser()); //true
②
enum UserType implements IsUser{
USER("USER"){
@Override
public boolean isUser() {
return true;
}
},CUSTOMER("CUSTOMER"){
@Override
public boolean isUser() {
return false;
}
};
private String userType;
private boolean isUser;
UserType(String userType,boolean isUser){
this.userType=userType;
this.isUser=isUser;
}
}
System.out.println(UserType.USER.isUser()); //true
③使用介面組織列舉
public interface IsUser{
enum UserType implements IsUser{
USER,CUSTOMER;
}
}
System.out.println(IsUser.UserType.USER); // USER
3.列舉中的方法
基礎類 Enum<T>
為自動繼承它的列舉例項提供了一些非常有用的方法。
方法 | 描述 |
---|---|
String name() | 返回列舉宣告宣告的列舉常量的名稱 |
int ordinal() | 返回列舉常量的次序(即列舉宣告時的位置,初始常量分配的位置是0) |
Java編譯器為每個列舉型別自動生成兩個更有用的靜態方法(讓我們將這個特殊的列舉型別假設為T)。
方法 | 描述 |
---|---|
T[] values() | 返回列舉T所宣告的所有常量 |
T valueOf(String name) | 返回指定名稱的列舉常量 |
System.out.println(UserType.valueOf("USER")); // 呼叫toString方法
System.out.println(UserType.USER.ordinal()); // 0
上面程式碼中valueOf()的引數值為 例項名的字串形式
,不是該例項的變數值
4.專用集合EnumSet和EnumMap
和所有其他類一樣,列舉的例項也可以和標準Java集合庫一起使用。然而,某些集合型別針對列舉做了優化,並且在大多數情況下推薦使用這些優化過後的集合代替通用的集合。
我們首先來看一下EnumSet集合。EnumSet集合是常規的集合優化過後高效儲存列舉型別的一個集合,EnumSet不能夠使用構造器進行例項化,但是它提供了很多非常有用的工廠方法。
// allOf工廠方法建立的EnumSet<T>例項就包含了所有列舉型別所列舉的常量:
final Set<DaysOfTheWeek> enumSetAll = EnumSet.allOf(DaysOfTheWeek.class);
//noneOf工廠方法建立的是一個空的EnumSet<T>例項
final Set<DaysOfTheWeek> enumSetNone = EnumSet.noneOf(DaysOfTheWeek.class);
//使用of工廠方法,可以指定列舉型別中那些列舉常量應該包含在EnumSet<T>中:
final Set< DaysOfTheWeek > enumSetSome = EnumSet.of(
DaysOfTheWeek.SUNDAY,
DaysOfTheWeek.SATURDAY
);
EnumMap<T, ?>是最接近於一般的map的,唯一的不同就是EnumMap<T, ?>的key是列舉型別的列舉常量
final Map<DaysOfTheWeek, String> enumMap = new EnumMap<>(UserType.class);
enumMap.put(UserType.USER, "Lundi");
三、列舉和常量的比較
使用常量時
- 常量作為引數時,是String,int等弱型別,開發人員可以傳入沒有在常量介面裡定義的值,這個問題無法通過編譯器發現。
- 由於開發人員可以直接寫常量,所以不能用==對比,只能用equals對比,不能優化效能。
- 開發人員沒有參考資料時,不可能知道某個int型別的引數到底應該賦什麼內容。
- 編譯時,是直接把常量的值編譯到類的二進位制程式碼裡,常量的值在升級中變化後,需要重新編譯引用常量的類,因為裡面存的是舊值。
- 如果常量類的構造器不私有,無法限制開發員繼承/實現介面,開發員能夠在子介面裡繼續新增常量.而這些常量可能得不到祖先層的支援。
使用列舉時
- 私有建構函式,避免被繼承和擴充套件。
- 定義方法的引數時,必須用列舉常量類型別,如上面的Constant,這樣就轉變成了強型別,不會出現弱型別引用的問題。
- 常量值地址唯一,可以用==直接對比,效能會有提高。
- 編譯時,沒有把常量值編譯到程式碼裡,即使常量的值發生變化,也不會影響引用常量的類。
相關文章
- 【java基礎】列舉Java
- 【java基礎】--Java列舉Java
- ?Java基礎之Java列舉Java
- java基礎:enum列舉Java
- java基礎(十一) 列舉型別Java型別
- 【Java基礎】列舉和註解Java
- Java基礎(十)——列舉與註解Java
- Java基礎教程(15)–列舉型別Java型別
- JAVA 基礎 - ENUM 列舉的簡單使用Java
- JAVA基礎:再談在Java中使用列舉(轉)Java
- JavaSE基礎:列舉型別Java型別
- Java列舉Java
- Java 列舉、JPA 和 PostgreSQL 列舉JavaSQL
- Java 列舉(enum)Java
- java列舉類Java
- Java列舉使用Java
- JAVA基礎--二維陣列Java陣列
- Java(4)列舉類Java
- 【java】【列舉使用技巧】Java
- Java列舉解讀Java
- java列舉型別Java型別
- java 列舉型別Java型別
- java中的列舉Java
- java基礎(十) 陣列型別Java陣列型別
- 【Java基礎知識】Java陣列與集合Java陣列
- Java列舉-通過值查詢對應的列舉Java
- Java enum列舉類詳解 列舉的常見用法Java
- 深入理解 Java 列舉Java
- Java - Enum 列舉型別Java型別
- Java 列舉 switch的用法Java
- Java —— 列舉類(enum 類)Java
- java_06列舉類Java
- Java 列舉 enum 詳解Java
- JAVA(四)類集/列舉Java
- java中列舉(Enum)使用Java
- JAVA列舉使用詳解Java
- 再談java列舉enumJava
- [Coursera]演算法基礎_Week2_列舉_Q1演算法