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

Java Enum 列舉類型綜合應用指南:紅綠燈狀態機、介面實作、內建方法與設計模式

     編輯:Java 相關知識

Java Enum 進階應用:從基礎語法到狀態機設計模式

Java 5 引入 enum 類型,不僅是常數集合,更是功能完整的類別,支援欄位、方法、介面實作、匿名內部類別覆寫。本文以紅綠燈狀態機為例,全面解析 Enum 進階特性與設計模式應用。

紅綠燈狀態機完整實作

public class TrafficLightDemo {
    public static void main(String[] args) {
        TrafficLight light = TrafficLight.RED;
        
        System.out.println("當前狀態: " + light);           // RED
        System.out.println("持續時間: " + light.getTime()); // 30
        System.out.println("下一狀態: " + light.nextLight()); // YELLOW
        System.out.println("宣告順序: " + light.ordinal());  // 1
        
        // 遍歷所有列舉值
        System.out.println("所有狀態:");
        for (TrafficLight l : TrafficLight.values()) {
            System.out.println("  " + l.name() + " (ordinal=" + l.ordinal() + ")");
        }
        
        // 字串轉列舉 (大小寫敏感)
        System.out.println("RED == valueOf(\"RED\"): " + (TrafficLight.RED == TrafficLight.valueOf("RED"))); // true
    }
}

enum TrafficLight {
    // 每個列舉常數是 TrafficLight 的匿名子類別實例
    GREEN(30) {
        @Override public TrafficLight nextLight() { return RED; }
    },
    RED(30) {
        @Override public TrafficLight nextLight() { return YELLOW; }
    },
    YELLOW(10) {
        @Override public TrafficLight nextLight() { return GREEN; }
    };
    
    // 抽象方法強制各常數實作
    public abstract TrafficLight nextLight();
    
    // 共享欄位與建構子
    private final int time;
    private TrafficLight(int time) { this.time = time; }
    public int getTime() { return time; }
}

Enum 核心特性深度解析

特性說明範例
類別本質隱含 final、繼承 java.lang.Enum、不可再繼承enum E {} → class E extends Enum<E>
常數實例每個常數是唯一實例,JVM 保證單例TrafficLight.RED == TrafficLight.RED (true)
建構子只能 private,常數宣告時呼叫RED(30) 呼叫 private TrafficLight(int)
匿名子類別大括號內可覆寫方法,每個常數可有不同行為GREEN { nextLight() { return RED; } }
介面實作可實作介面,每個常數可不同實作enum E implements I { A { m(){} }, B { m(){} } }
靜態導入import static pkg.E.*; 直接使用 A, B

內建實用方法

TrafficLight[] all = TrafficLight.values();        // 所有常數陣列 (依宣告順序)
TrafficLight red = TrafficLight.valueOf("RED");    // 字串轉常數 (不存在拋 IllegalArgumentException)
String name = TrafficLight.RED.name();             // "RED" (不可覆寫)
int ordinal = TrafficLight.RED.ordinal();          // 0-based 宣告索引
Class<TrafficLight> clazz = TrafficLight.RED.getDeclaringClass(); // 列舉類別 Class
int compare = TrafficLight.RED.compareTo(TrafficLight.GREEN); // 比較 ordinal

EnumSet / EnumMap 高效能集合

// EnumSet: 位元向量實作,極度高效
Set active = EnumSet.of(TrafficLight.RED, TrafficLight.GREEN);
Set all = EnumSet.allOf(TrafficLight.class);
Set range = EnumSet.range(TrafficLight.RED, TrafficLight.YELLOW);

// EnumMap: 陣列實作,鍵為 Enum 時比 HashMap 快數倍
Map desc = new EnumMap<>(TrafficLight.class);
desc.put(TrafficLight.RED, "停止");
desc.put(TrafficLight.GREEN, "通行");

進階設計模式應用

策略模式:每個常數封裝不同演算法

enum PayStrategy {
    ALIPAY { public void pay(double amt) { System.out.println("支付寶付款: " + amt); }},
    WECHAT { public void pay(double amt) { System.out.println("微信付款: " + amt); }},
    CREDIT_CARD { public void pay(double amt) { System.out.println("信用卡付款: " + amt); }};
    public abstract void pay(double amount);
}

// 使用
PayStrategy.ALIPAY.pay(100.0);

狀態模式:狀態轉換邏輯內聚

enum OrderState {
    PENDING {
        @Override public OrderState next() { return PAID; }
        @Override public void handle(Order ctx) { ctx.setPaidTime(now()); }
    },
    PAID {
        @Override public OrderState next() { return SHIPPED; }
        @Override public void handle(Order ctx) { ctx.setShipTime(now()); }
    },
    SHIPPED { @Override public OrderState next() { return DONE; }},
    DONE { @Override public OrderState next() { return this; }};
    public abstract OrderState next();
    public abstract void handle(Order ctx);
}

單例模式:最簡單、線程安全、防序列化破壞

enum Singleton {
    INSTANCE;
    private Resource resource;
    public Resource getResource() { return resource; }
}
// 使用: Singleton.INSTANCE.getResource()

序列化特殊保障

  • Enum 序列化僅寫入常數名稱,反序列化透過 valueOf 還原
  • 不受 serialVersionUID、transient、readObject/writeObject 影響
  • 絕對保證單例特性,即使跨 JVM 序列化傳輸

Enum 是 Java 型別系統威力的展現:型別安全、行為封裝、高效能集合、設計模式原生支援,善用之可大幅提升代碼品質。

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