重新认识枚举enum
定义
在 Java 中,enum(枚举)是一种特殊的类,用于定义固定数量的常量集合。它从 JDK 5(Java 1.5) 开始引入,目的是替代传统的 public static final int 常量,提供类型安全、可读性强、功能丰富的常量管理方式
publicenumDay{MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;}扩展
publicenumDay{MONDAY("MONDAY",0),TUESDAY("TUESDAY",1);}相当于
publicfinalclassDayextendsjava.lang.Enum<Day>{publicstaticfinalDayMONDAY=newDay("MONDAY",0);publicstaticfinalDayTUESDAY=newDay("TUESDAY",1);// ... 其他常量privateDay(Stringname,intordinal){super(name,ordinal);}publicstaticDay[]values(){/* 返回所有常量 */}publicstaticDayvalueOf(Stringname){/* 根据名字返回常量 */}}内置常用方法
| 方法 | 作用 | 示例 |
|---|---|---|
values() | 返回所有常量数组 | Day[] days = Day.values(); |
valueOf(String) | 根据名称返回常量 | Day d = Day.valueOf("MONDAY"); |
ordinal() | 返回声明索引 | Day.MONDAY.ordinal() → 0 |
name() | 返回常量名称 | Day.MONDAY.name() → "MONDAY" |
compareTo() | 按声明顺序比较 | MONDAY.compareTo(TUESDAY) → -1 |
在 Java 中,枚举类(enum)的构造函数参数数量没有硬性限制
publicenumPlanet{EARTH(1,"blue",9.8,true,"Solar System",...);// 理论上可继续添加Planet(doublemass,Stringcolor,doublegravity,booleanhabitable,Stringsystem/*, ...*/){// 构造逻辑}}| 问题 | 说明 |
|---|---|
| 代码可读性崩溃 | 超过 5-10 个参数已难以维护(违反 Clean Code 原则) |
| 编译错误 | 某些 IDE 或编译器可能提前报错(如 Eclipse 限制方法参数 ≤ 255,但实际更早失败) |
| 字节码膨胀 | 大量参数导致.class文件臃肿 |
添加字段,构造方法等
在 Java 中,enum(枚举)不仅可定义常量列表,还可以像普通类一样:
- 添加字段(成员变量)
- 定义构造函数
- 声明方法(包括抽象方法)
- 实现接口
这使得 enum 非常强大,适用于需要为每个常量附加数据或行为的场景。
publicenumPlanet{// 枚举常量(必须在最前面,调用构造函数)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)privatefinaldoublemass;// 质量(kg)privatefinaldoubleradius;// 半径(m)// 构造函数(只能是 private 或 package-private,默认 private)Planet(doublemass,doubleradius){this.mass=mass;this.radius=radius;}// 方法publicdoublegetMass(){returnmass;}publicdoublegetRadius(){returnradius;}// 计算表面重力:g = G * M / r^2publicdoublesurfaceGravity(){return6.67300E-11*mass/(radius*radius);}// 计算某物体在该星球上的重量publicdoublesurfaceWeight(doubleotherMass){returnotherMass*surfaceGravity();}}publicclassMain{publicstaticvoidmain(String[]args){Planetearth=Planet.EARTH;System.out.println("Earth's gravity: "+earth.surfaceGravity());System.out.println("My weight on Mars: "+Planet.MARS.surfaceWeight(70));// 70kg 人在火星的重量}}内置常用方法
高级用法:每个常量有不同行为(抽象方法)
publicenumOperation{PLUS{publicdoubleapply(doublex,doubley){returnx+y;}},MINUS{publicdoubleapply(doublex,doubley){returnx-y;}},TIMES{publicdoubleapply(doublex,doubley){returnx*y;}},DIVIDE{publicdoubleapply(doublex,doubley){returnx/y;}};// 抽象方法 → 每个常量必须实现publicabstractdoubleapply(doublex,doubley);}doubleresult=Operation.PLUS.apply(5,3);// 8.0| 特性 | 说明 |
|---|---|
| 枚举常量必须在第一行 | 所有CONSTANT(...)必须出现在字段/方法之前 |
构造函数只能是private | 不能public或protected(防止外部 new) |
字段建议用final | 枚举常量通常是不可变的 |
| 可以实现接口 | enum MyEnum implements Runnable { ... } |
| 不能继承其他类 | 因为enum隐式继承java.lang.Enum(Java 不支持多继承) |
| 可以有静态方法/字段 | 如values(),valueOf(String)是自动生成的 |
总结
Java 的 enum 远不止是“常量集合”,它是一个功能完整的类,支持:
字段 + 构造函数 + 方法 + 接口 + 多态行为
合理使用能让代码更安全、清晰、可维护,是 Java 中被低估的强大特性。
