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

Java Enum 枚舉完全指南:從基礎用法到單例模式最佳實踐

     編輯:Java 相關知識

為什麼選 Enum

  • 類型安全:編譯期檢查,杜絕非法常量
  • 單例天然線程安全:JVM 保證初始化原子性
  • 豐富 API:values()、valueOf()、ordinal()、name()
  • 可攜帶字段、方法、實現接口
  • switch 支持、序列化安全、防反射攻擊

基礎語法


public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

// 遍歷
for (Day d : Day.values()) System.out.println(d);

// switch (Java 12+ 增強)
String type = switch (day) {
    case MONDAY, FRIDAY -> "工作日";
    case SATURDAY, SUNDAY -> "週末";
    default -> "未知";
};

帶字段與方法的枚舉


public enum Planet {
    MERCURY(3.303e+23, 2.4397e6),
    VENUS  (4.869e+24, 6.0518e6),
    EARTH  (5.976e+24, 6.37814e6),
    MARS   (6.421e+23, 3.3972e6);

    private final double mass;   // kg
    private final double radius; // m

    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }

    public double mass() { return mass; }
    public double radius() { return radius; }

    // 通用常量
    public static final double G = 6.67300E-11;

    // 實例方法
    public double surfaceGravity() {
        return G * mass / (radius * radius);
    }
    public double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }

    public static void main(String[] args) {
        double earthWeight = 70; // kg
        for (Planet p : Planet.values()) {
            System.out.printf("%s: 表面重力=%.2f, 体重=%.2f N%n",
                p, p.surfaceGravity(), p.surfaceWeight(earthWeight));
        }
    }
}

枚舉實現接口 —— 策略模式優雅落地


public interface Operation {
    double apply(double x, double y);
}

public enum Op implements Operation {
    PLUS   { public double apply(double x, double y) { return x + y; } },
    MINUS  { public double apply(double x, double y) { return x - y; } },
    TIMES  { public double apply(double x, double y) { return x * y; } },
    DIVIDE { public double apply(double x, double y) { return x / y; } };

    public static void main(String[] args) {
        double x = 10, y = 5;
        for (Op op : Op.values())
            System.out.printf("%s: %.1f%n", op, op.apply(x, y));
    }
}

枚舉實現單例 —— 最佳實踐


public enum Singleton {
    INSTANCE;

    private final String[] initArgs = {"arg1", "arg2"};

    public String[] getInitArgs() { return initArgs.clone(); }

    public void doSomething() { System.out.println("Singleton working..."); }
}

// 使用
Singleton.INSTANCE.doSomething();

優勢:防反射破壞、防序列化重建、代碼極簡、延遲加載(類加載機制天然保證)。

EnumSet & EnumMap —— 高性能專用集合


// EnumSet: 位向量實現,極快
EnumSet workDays = EnumSet.range(Day.MONDAY, Day.FRIDAY);
EnumSet weekend = EnumSet.complementOf(workDays);

// EnumMap: 數組實現,key 為 enum 時比 HashMap 快 2-3 倍
EnumMap schedule = new EnumMap<>(Day.class);
schedule.put(Day.MONDAY, "會議");
schedule.put(Day.FRIDAY, "總結");

避坑指南

誤區正確做法
用 ordinal() 存數據庫用 name() 或自定義 code 字段,防止插入新枚舉導致序號錯亂
大量實例字段導致內存膨脹枚舉實例是單例,字段極少時無影響;大量數據外置配置表
switch 未覆蓋所有常量Java 12+ switch 表達式強制 exhaustive,漏寫編譯報錯
嘗試繼承枚舉enum 隱式 final,不可繼承;改用接口 + 實現類

總結

Enum 不只是「常量集合」,更是「受限制的類」。善用它實現單例、策略、狀態機、位掩碼,代碼更安全、更清晰、更高效。

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