← 返回首页

Java枚举类型详解

📂 java ⏱ 3 min 587 words

什么是枚举

枚举(Enum)是JDK 5引入的一种特殊的数据类型,用于表示固定的常量集合。枚举类型是隐式继承java.lang.Enum的final类。

基本枚举定义

public enum Season {
    SPRING, SUMMER, AUTUMN, WINTER
}

public class EnumBasicDemo {
    public static void main(String[] args) {
        Season spring = Season.SPRING;
        System.out.println("季节: " + spring);
        System.out.println("名称: " + spring.name());
        System.out.println("序号: " + spring.ordinal());

        Season summer = Season.valueOf("SUMMER");
        System.out.println("valueOf结果: " + summer);

        Season[] seasons = Season.values();
        for (Season s : seasons) {
            System.out.println(s + " -> " + s.ordinal());
        }
    }
}

枚举中添加属性和方法

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),
    JUPITER(1.9e+27, 7.1492e7);

    private final double mass;
    private final double radius;

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

    private static final double G = 6.67300E-11;

    public double surfaceGravity() {
        return G * mass / (radius * radius);
    }

    public double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }
}

public class EnumPropertyDemo {
    public static void main(String[] args) {
        double earthWeight = 75.0;
        System.out.println("地球体重: " + earthWeight + " kg");

        for (Planet planet : Planet.values()) {
            System.out.printf("%s表面体重: %.2f kg%n",
                planet.name(), planet.surfaceWeight(earthWeight));
        }
    }
}

枚举实现接口

public interface Describable {
    String describe();
}

public enum Color implements Describable {
    RED("红色", "#FF0000"),
    GREEN("绿色", "#00FF00"),
    BLUE("蓝色", "#0000FF"),
    YELLOW("黄色", "#FFFF00");

    private final String chineseName;
    private final String hexCode;

    Color(String chineseName, String hexCode) {
        this.chineseName = chineseName;
        this.hexCode = hexCode;
    }

    public String getChineseName() {
        return chineseName;
    }

    public String getHexCode() {
        return hexCode;
    }

    @Override
    public String describe() {
        return chineseName + " (" + hexCode + ")";
    }
}

public class EnumInterfaceDemo {
    public static void main(String[] args) {
        for (Color color : Color.values()) {
            System.out.println(color.describe());
        }
    }
}

枚举实现抽象方法

public abstract class Operation {
    public abstract double apply(double x, double y);

    public static final Operation PLUS = new Operation() {
        @Override
        public double apply(double x, double y) {
            return x + y;
        }
    };

    public static final Operation MINUS = new Operation() {
        @Override
        public double apply(double x, double y) {
            return x - y;
        }
    };
}

public enum CalculatorOperation {
    ADD {
        @Override
        public double apply(double x, double y) {
            return x + y;
        }
    },
    SUBTRACT {
        @Override
        public double apply(double x, double y) {
            return x - y;
        }
    },
    MULTIPLY {
        @Override
        public double apply(double x, double y) {
            return x * y;
        }
    },
    DIVIDE {
        @Override
        public double apply(double x, double y) {
            if (y == 0) throw new ArithmeticException("除数不能为零");
            return x / y;
        }
    };

    public abstract double apply(double x, double y);
}

public class EnumAbstractMethodDemo {
    public static void main(String[] args) {
        double x = 10, y = 3;

        for (CalculatorOperation op : CalculatorOperation.values()) {
            System.out.printf("%.1f %s %.1f = %.2f%n",
                x, op.name(), y, op.apply(x, y));
        }
    }
}

枚举单例模式

public enum Singleton {
    INSTANCE;

    private int counter = 0;

    public void doSomething() {
        counter++;
        System.out.println("执行操作次数: " + counter);
    }

    public int getCounter() {
        return counter;
    }
}

public class EnumSingletonDemo {
    public static void main(String[] args) {
        Singleton s1 = Singleton.INSTANCE;
        Singleton s2 = Singleton.INSTANCE;

        System.out.println("是否同一实例: " + (s1 == s2));

        s1.doSomething();
        s2.doSomething();
        System.out.println("总计: " + s1.getCounter());
    }
}

EnumSet和EnumMap

import java.util.EnumMap;
import java.util.EnumSet;

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

    public static void main(String[] args) {
        EnumSet<Day> weekdays = EnumSet.range(Day.MONDAY, Day.FRIDAY);
        System.out.println("工作日: " + weekdays);

        EnumSet<Day> weekend = EnumSet.of(Day.SATURDAY, Day.SUNDAY);
        System.out.println("周末: " + weekend);

        EnumSet<Day> allDays = EnumSet.allOf(Day.class);
        System.out.println("所有天: " + allDays);

        EnumMap<Day, String> dayActivities = new EnumMap<>(Day.class);
        dayActivities.put(Day.MONDAY, "开会");
        dayActivities.put(Day.TUESDAY, "编码");
        dayActivities.put(Day.WEDNESDAY, "代码审查");

        dayActivities.forEach((day, activity) ->
            System.out.println(day + ": " + activity));
    }
}

枚举最佳实践

  1. 枚举是线程安全的,适合作为单例
  2. 使用枚举代替常量类
  3. 枚举可以有构造方法、字段和方法
  4. 枚举值是编译时常量
  5. 使用EnumSet和EnumMap提高性能

总结

枚举是Java中强大的类型安全工具,不仅可以定义常量,还可以包含方法和实现接口。掌握枚举的使用能让你的代码更加清晰、安全和易于维护。