1、簡介
不知道大家有沒有在自己項目中看到過類似下面這樣的代碼:
public static void fruitsHandle(String fruits) {
switch (fruits) {
case "Apple":
// TODO
break;
case "Banana":
case "Orange":
default:
throw new IllegalStateException("Unexpected value: " + fruits);
}
}
出現上面這種情況是非常少的,小萌新一般也不會直接在方法中重複定義字元串進行比較,而會将其定義為常量,或者統一抽取為常量類。是以一般會看到這種代碼(小捌經常在項目中看到類似這樣的代碼,但是小捌不敢吭聲😄😄):
private static final String APPLE = "Apple";
private static final String BANANA = "Banana";
private static final String ORANGE = "Orange";
case APPLE:
case BANANA:
case ORANGE:
上面這種情況我們在代碼中出現的頻率非常高;它需要程式員提供一組固定常量,并且這一組固定常量在開發時或者說編譯時就知道了具體的成員,這個時候我們就應該使用枚舉。
枚舉類型(enum type)是指由一組固定常量組成合法值的類型。
2、優勢
使用枚舉類型,相比直接定義常量能夠帶來非常多的好處。
2.1 類型安全
分别定義一個簡單的肉類枚舉和水果枚舉
// 肉類枚舉
public enum MeetEnums {
BEEF,
PORK,
FISH;
// 水果枚舉
public enum FruitsEnums {
APPLE,
BANANA,
ORANGE;
我們改造上面的代碼,修改入參類型即可
public static void fruitsHandle(FruitsEnums fruits) {
可以看到定義枚舉類型帶來函數類型安全性,如果定義的是常量則無法代理這種效果
2.2 枚舉能夠提供更多資訊
枚舉在本質上還是一個類,它能夠定義屬性和方法,我們可以在枚舉類中定義想要的方法、或者通過屬性擴充枚舉提供的基礎資訊。
比如我們做web開發時最常見的HttpStatus,在springframework架構中就被定義成了枚舉類,它不僅包含了Http響應碼,還能包含描述狀态。
public enum HttpStatus {
OK(200, "OK"),
NOT_FOUND(404, "Not Found"),
INTERNAL_SERVER_ERROR(500, "Internal Server Error");
private final int value;
private final String reasonPhrase;
private HttpStatus(int value, String reasonPhrase) {
this.value = value;
this.reasonPhrase = reasonPhrase;
2.3 通過函數提供更多服務
此外HttpStatus它内部還嵌套了Series枚舉類,這個類可以協助HttpStatus枚舉類,通過statusCode / 100的模判斷目前的枚舉狀态是is1xxInformational、is2xxSuccessful、is3xxRedirection、is4xxClientError、is5xxServerError等等。
public static enum Series {
INFORMATIONAL(1),
SUCCESSFUL(2),
REDIRECTION(3),
CLIENT_ERROR(4),
SERVER_ERROR(5);
private final int value;
private Series(int value) {
this.value = value;
}
public int value() {
return this.value;
public static HttpStatus.Series valueOf(HttpStatus status) {
return valueOf(status.value);
public static HttpStatus.Series valueOf(int statusCode) {
HttpStatus.Series series = resolve(statusCode);
if (series == null) {
throw new IllegalArgumentException("No matching constant for [" + statusCode + "]");
} else {
return series;
}
@Nullable
public static HttpStatus.Series resolve(int statusCode) {
int seriesCode = statusCode / 100;
HttpStatus.Series[] var2 = values();
int var3 = var2.length;
for(int var4 = 0; var4 < var3; ++var4) {
HttpStatus.Series series = var2[var4];
if (series.value == seriesCode) {
return series;
}
return null;
2.4 擷取所有定義的類型
所有的枚舉類會自動産生一個values()方法,它能傳回目前定義枚舉類的數組集,是以可以很友善的周遊怎麼枚舉類定義的所有枚舉。比如我們簡單改造一下MeetEnums枚舉類:
BEEF("牛肉"),
PORK("豬肉"),
FISH("魚肉");
String name;
public String getName() {
return name;
MeetEnums(String name) {
this.name = name;
public static MeetEnums getMeetEnumsByName(String name) {
MeetEnums[] values = values();
Optional<MeetEnums> optional = Stream.of(values).filter(v -> v.getName().equals(name)).findAny();
return optional.isPresent() ? optional.get() : null;
總之枚舉類相比常量來說有太多的優點,它能使得代碼更加整潔美觀、安全性強、功能強大。雖然大部分情況下,枚舉類的選擇是由于常量定義的,但是也并不是任何時候都一定要把常量定義成枚舉;具體情況大家就可以自己去斟酌啦!