Java枚举类型详解
什么是枚举
枚举(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));
}
}
枚举最佳实践
- 枚举是线程安全的,适合作为单例
- 使用枚举代替常量类
- 枚举可以有构造方法、字段和方法
- 枚举值是编译时常量
- 使用EnumSet和EnumMap提高性能
总结
枚举是Java中强大的类型安全工具,不仅可以定义常量,还可以包含方法和实现接口。掌握枚举的使用能让你的代码更加清晰、安全和易于维护。