Thinking in Java(4-7) 列舉型別(enum)

Thinking in Java(4-7) 列舉型別(enum)
Photo by orbtal media / Unsplash

Java SE5 引入了 enum 關鍵字,這是對 Java 語言的一項重大擴充,使得定義常數更加安全和方便。在此之前,常數通常是以整數或字串常量的形式定義,這不能保證只使用限定的值,存在使用錯誤的風險。

基本列舉的定義

public enum Spiciness {
  NOT, MILD, MEDIUM, HOT, FLAMING
}
  • 這段程式碼定義了一個名為 Spiciness 的列舉,包含五個不同的辣度等級。
  • 每個列舉實例都對應一個固定的整數索引,稱為序數(ordinal),從 0 開始。

列舉在運行時的行為

為了使用 enum,需要建立該型別的參考,並賦值給某個實例:

public class EnumOrder {
  public static void main(String[] args) {
    for(Spiciness s : Spiciness.values())
      System.out.println(s + ", ordinal " + s.ordinal());
  }
} /* Output:
NOT, ordinal 0
MILD, ordinal 1
MEDIUM, ordinal 2
HOT, ordinal 3
FLAMING, ordinal 4
*/
  • values() 方法是編譯器自動生成的,返回一個包含所有列舉實例的陣列。
  • ordinal() 方法返回每個列舉實例的序數。

列舉的進階特性

雖然 enum 看起來像是一個全新的資料型別,但實際上它在背後是由編譯器生成的特殊類別。這意味著列舉可以擁有方法和屬性,並且可以被當作其他任何類別來處理。

  • 列舉實際上是類別enum 本質上是繼承自 java.lang.Enum 的特殊類別,因此可以添加方法、建構子和屬性。

在 switch 語句中使用列舉

列舉特別適合在 switch 語句中使用,因為它們可以清晰地限制可能的選項,這使得程式碼更加安全和易於維護:

public class Burrito {
  Spiciness degree;
  public Burrito(Spiciness degree) { this.degree = degree;}
  public void describe() {
    System.out.print("This burrito is ");
    switch(degree) {
      case NOT:    System.out.println("not spicy at all.");
                   break;
      case MILD:
      case MEDIUM: System.out.println("a little hot.");
                   break;
      case HOT:
      case FLAMING:
      default:     System.out.println("maybe too hot.");
    }
  }	
  public static void main(String[] args) {
    Burrito
      plain = new Burrito(Spiciness.NOT),
      greenChile = new Burrito(Spiciness.MEDIUM),
      jalapeno = new Burrito(Spiciness.HOT);
    plain.describe();
    greenChile.describe();
    jalapeno.describe();
  }
} /* Output:
This burrito is not spicy at all.
This burrito is a little hot.
This burrito is maybe too hot.
*/
  • 使用列舉在 switch 語句中能夠更精確地控制流程,並確保所有情況都被涵蓋,減少錯誤。
  • switch 語句中的每個 case 都使用列舉的實例,這使得程式碼更加易讀和易於維護。

列舉的其他特性

  • 添加方法和屬性:由於列舉實際上是類別,因此可以為其添加方法、屬性和建構子。
public enum Spiciness {
  NOT("Not Spicy"), 
  MILD("Mildly Spicy"), 
  MEDIUM("Medium Spicy"), 
  HOT("Hot"), 
  FLAMING("Extremely Hot");
  
  private String description;
  
  private Spiciness(String description) {
    this.description = description;
  }
  
  public String getDescription() {
    return description;
  }
}
    • 在這個範例中,為每個列舉實例添加了一個描述,並提供了一個方法 getDescription() 來獲取該描述。
  • 覆寫方法:可以覆寫 toString() 方法,以自定義列舉實例的字串表示。
  • 使用列舉實現設計模式:列舉可以用於實現單例模式、狀態模式等,充分利用其類別特性。

列舉的優點

  • 類型安全:列舉提供了類型安全,避免了使用整數或字串常量時可能出現的錯誤。
  • 可讀性高:列舉的使用使程式碼更具可讀性和意義明確。
  • 易於維護:添加或修改列舉實例時,不會影響到使用該列舉的程式碼,減少了維護成本。

結論

Java 的 enum 關鍵字為開發者提供了一種強大而靈活的方式來定義常數集合。透過使用列舉,可以提高程式碼的安全性、可讀性和維護性。列舉不僅可以在 switch 語句中使用,還可以擁有自己的方法和屬性,甚至實現複雜的設計模式,是 Java 語言中一個非常有用的特性。