首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java Enum 枚舉類型深度解析:特性、遍歷、常用方法與實戰應用

     編輯:Java 程式設計入門

前言

自 Java 5 引入 enum 關鍵字以來,枚舉類型已成為表達「固定常量集合」的首選方案。它不僅提供型別安全,還具備豐富的物件導向特性。本文將系統梳理枚舉的核心特點、遍歷方式、常用方法、建構子用法,並以「交通燈狀態機」為例展示實戰應用。

一、枚舉核心特性

1. 隱式繼承 java.lang.Enum

使用 enum 定義的類別,預設繼承 java.lang.Enum 而非 Object。Enum 類別實作了 Serializable 與 Comparable 介面,因此枚舉實例天生可序列化、可比較。

2. 建構子預設為 private

枚舉的建構子只能是 private(省略修飾符時預設為 private),這保證了外部無法透過 new 建立新實例,確保實例數量固定。

3. 實例必須在枚舉類別中顯式列出

所有實例必須在枚舉定義的開頭以逗號分隔列出,結尾以分號結束。系統會自動為每個實例添加 public static final 修飾符。

範例:帶有自訂方法的星期枚舉

public enum Week {
    MON {
        public String toLocaleString() { return "星期一"; }
    },
    TUE {
        public String toLocaleString() { return "星期二"; }
    },
    WED {
        public String toLocaleString() { return "星期三"; }
    },
    THU {
        public String toLocaleString() { return "星期四"; }
    },
    FRI {
        public String toLocaleString() { return "星期五"; }
    },
    SAT {
        public String toLocaleString() { return "星期六"; }
    },
    SUN {
        public String toLocaleString() { return "星期日"; }
    };

    // 定義抽象方法,強制每個實例實作
    public abstract String toLocaleString();
}

二、枚舉遍歷

透過 values() 靜態方法獲取所有實例陣列,配合增強型 for 迴圈遍歷:

public class EnumTest {
    public static void main(String[] args) {
        for (Week w : Week.values()) {
            System.out.println(w); // 輸出:MON, TUE, ...
        }
    }
}

三、常用方法詳解

方法說明
int compareTo(E o)比較兩個枚舉常數的宣告順序
String name()返回枚舉常數的名稱(如 "MON")
int ordinal()返回枚舉常數的索引(從 0 開始)
String toString()返回常數名稱,可覆寫以提供更友善輸出
static <T> T valueOf(String name)根據名稱字串返回對應的枚舉常數
values()返回包含所有枚舉常數的陣列

程式碼示範

public class EnumTest {
    public static void main(String[] args) {
        Week day = Week.FRI;
        System.out.println(day);                    // FRI
        System.out.println(day.name());             // FRI
        System.out.println(day.ordinal());          // 4
        System.out.println(Week.valueOf("SUN").toLocaleString()); // 星期日
        System.out.println(Week.values().length);   // 7
    }
}

四、枚舉建構子與屬性

枚舉可擁有屬性、建構子與方法,實現豐富的行為:

public enum Gender {
    MALE("男"), FEMALE("女");

    private final String name;

    private Gender(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return name;
    }
}

五、綜合實戰:交通燈狀態機

利用枚舉的「單例特性」與「可攜帶行為」特點,優雅實現交通燈狀態轉換邏輯:

交通燈狀態機示意圖

public enum Lamp {
    // 主幹道直行燈(帶有對向燈、下一燈、初始亮滅狀態)
    S2N("N2S", "S2W", false),
    S2W("N2E", "E2W", false),
    E2W("W2E", "E2S", false),
    E2S("W2N", "S2N", false),

    // 相反方向燈(不參與循環,僅作對向參考)
    N2S(null, null, false),
    N2E(null, null, false),
    W2E(null, null, false),
    W2N(null, null, false),

    // 右轉燈(假想永遠綠燈)
    S2E(null, null, true),
    E2N(null, null, true),
    N2W(null, null, true),
    W2S(null, null, true);

    private final String opposite;  // 對向燈名稱
    private final String next;      // 下一個綠燈名稱
    private boolean lighted;        // 當前是否為綠燈

    private Lamp(String opposite, String next, boolean lighted) {
        this.opposite = opposite;
        this.next = next;
        this.lighted = lighted;
    }

    public boolean isLighted() { return lighted; }

    // 變綠:自身與對向燈同時變綠
    public void light() {
        this.lighted = true;
        if (opposite != null) Lamp.valueOf(opposite).light();
        System.out.println(name() + " lamp is green");
    }

    // 變紅:自身與對向燈變紅,觸發下一燈變綠
    public Lamp blackOut() {
        this.lighted = false;
        if (opposite != null) Lamp.valueOf(opposite).blackOut();

        Lamp nextLamp = null;
        if (next != null) {
            nextLamp = Lamp.valueOf(next);
            System.out.println("綠燈從 " + name() + " 切換為 " + next);
            nextLamp.light();
        }
        return nextLamp;
    }
}

六、最佳實踐建議

  • 用枚舉實現單例: 防止反射與序列化破壞,是《Effective Java》推薦的單例寫法
  • 策略模式替代品: 每個枚舉實例實作不同行為,替代大量 if-else 或 switch
  • 實作介面: 枚舉可實作一或多個介面,提供多型能力
  • 避免過度設計: 簡單常量集合無需強行加入複雜邏輯

總結

Java 枚舉遠不止「常量集合」,它是功能完整的類別,支援屬性、方法、介面實作與多型。善用枚舉能讓代碼更具型別安全、可讀性與擴展性。下次面對「固定數量的業務狀態」時,請優先考慮 enum。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved