很多初學者在剛開始使用枚舉的時候覺得它只是一個給常量命名的工具,比如 static constant String ENUM_VAL_NAME。
但其實Java的枚舉還有很多先進的功能,這些功能可以幫助開發者寫出更簡潔且不易出錯的代碼。
接下來我會列舉一些Java的高級枚舉功能,以及如何利用這些功能來使得開發更高效,更具可讀性。
枚舉是類
首先,我們要確認一點,枚舉是Java的一個類。
比如創建下面一段代碼,枚舉的基類Enum<E>
public abstract class Enum<E extends Enum<E>>
implements Constable, Comparable<E>, Serializable {
private final String name;
public final String name() {
return name;
}
private final int ordinal;
public final int ordinal() {
return ordinal;
}
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
public String toString() {
return name;
}
public final boolean equals(Object other) {
return this==other;
}
public final int hashCode() {
return super.hashCode();
}
public final int compareTo(E o) {
Enum<?> other = (Enum<?>)o;
Enum<E> self = this;
if (self.getClass() != other.getClass() && // optimization
self.getDeclaringClass() != other.getDeclaringClass())
throw new ClassCastException();
return self.ordinal – other.ordinal;
}
}
上述代碼是一個普通的抽象類,有兩個字段,name和ordinal。
由于枚舉都是類,所以我們能夠為枚舉提供實例方法、構造函數和字段,還可以重寫 toString()
Java中的Operation枚舉
enum Operation {
ADD,
SUBTRACT,
MULTIPLY
}
此枚舉表示可以對兩個值操作并將產生結果。
一般來說,初學者更偏向于使用switch 語句來完成這個功能,如下代碼所示:
public int apply(Operation operation, int arg1, int arg2) {
switch(operation) {
case ADD:
return arg1 + arg2;
case SUBTRACT:
return arg1 – arg2;
case MULTIPLY:
return arg1 * arg2;
default:
throw new UnsupportedOperationException();
}
}
這個實現存在一些問題。
①如果我們向Operation添加新操作,編譯器不會通知此switch沒有正確處理新的操作。
②遇到default情況,就算我們知道它永遠不會發生,這也是必需的。
但還好,Java 8 使用函數式編程為我們提供了一個干凈的解決方案。
功能枚舉實現
由于枚舉是類,我們可以創建一個枚舉字段來保存函數。如何來完成這一操作?
首先,讓我們將開關放在枚舉類中。
enum Operation {
ADD,
SUBTRACT,
MULTIPLY;
public static int apply(Operation operation, int arg1, int arg2) {
switch(operation) {
case ADD:
return arg1 + arg2;
case SUBTRACT:
return arg1 – arg2;
case MULTIPLY:
return arg1 * arg2;
default:
throw new UnsupportedOperationException();
}
}
}
可以做這樣的添加:Operation.apply(Operation.ADD, 2, 3);
上述代碼中是從 inside 調用方法Operation,可以將其更改為實例方法,并使用this關鍵字,而不是將所需的Operation作為參數傳遞。
public int apply(int arg1, int arg2) {
switch(this) {
case ADD:
return arg1 + arg2;
case SUBTRACT:
return arg1 – arg2;
case MULTIPLY:
return arg1 * arg2;
default:
throw new UnsupportedOperationException();
}
}
像這樣調用加法操作:Operation.ADD.apply(2, 3);
現在讓我們更進一步,通過使用函數式編程完全消除 switch 語句。
enum Operation {
ADD((x, y) -> x + y),
SUBTRACT((x, y) -> x – y),
MULTIPLY((x, y) -> x * y);
Operation(BiFunction<Integer, Integer, Integer> operation) {
this.operation = operation;
}
private final BiFunction<Integer, Integer, Integer> operation;
public int apply(int x, int y) {
return operation.apply(x, y);
}
}
上述代碼中做了三件事:
1.添加了一個BiFunction<Integer, Integer, Integer> operation字段。
2.Operation使用BiFunctionarg創建了一個構造函數。
3.調用構造函數BiFunction<Integer, Integer, Integer>并用
lambda指定。該
java.util.function.BiFunction operation字段是對帶有兩個參數的函數(方法)的引用。在上述代碼示例中,兩個參數都是整數,返回值也是整數。但是Java 參數化類型不支持原語,因此必須使用Integer。
新Operation實現以相同的方式使用:Operation.ADD.apply(2, 3),
但是,這種實現會比switch好一些,因為編譯器會在Operation添加新功能時會要求開發者實現新功能。
關鍵要點
Java 枚舉是擴展Enum<T>.
枚舉可以有字段、構造函數和實例方法。
Java 枚舉字段可以存儲函數與 lambda 配合使用,也可以創建一個函數的干凈、安全的特定于枚舉的實現,并在編譯時強制執行(不使用switch)。
以上就是Enum高階的使用方法,希望對你有幫助。
版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。