提起Java枚举(Enum),很多人第一反应是"把常量打包的语法糖",但这货的实力远不止表面------它能写方法、实现接口、甚至搞单例,堪称Java里被低估的"全能选手"。今天扒一扒枚举的进阶玩法,告别只会用它定义常量的尴尬。
一、枚举不只是"键值对":能写方法的特殊类
枚举本质是final修饰的类,每个枚举项都是它的实例。所以它能有成员变量、方法,甚至构造器(默认private,外界无法调用)。
java
public enum OrderStatus {
// 枚举项必须放在第一行,括号传参对应构造器
PENDING("待支付", 1),
PAID("已支付", 2),
SHIPPED("已发货", 3),
COMPLETED("已完成", 4);
// 成员变量
private final String desc;
private final int code;
// 构造器(private可省略,默认私有)
OrderStatus(String desc, int code) {
this.desc = desc;
this.code = code;
}
// 普通方法
public String getDesc() {
return desc;
}
// 静态方法:根据code查枚举
public static OrderStatus getByCode(int code) {
for (OrderStatus status : values()) {
if (status.code == code) {
return status;
}
}
throw new IllegalArgumentException("无效状态码:" + code);
}
}
// 测试
public class EnumTest {
public static void main(String[] args) {
System.out.println(OrderStatus.PAID.getDesc()); // 输出:已支付
System.out.println(OrderStatus.getByCode(3)); // 输出:SHIPPED
}
}
二、枚举实现接口:突破"常量"局限
枚举可以实现接口,让不同枚举项有不同的行为,比switch-case更优雅。
java
// 定义接口
interface Operation {
int calculate(int a, int b);
}
// 枚举实现接口
public enum Calculator implements Operation {
ADD {
@Override
public int calculate(int a, int b) {
return a + b;
}
},
SUBTRACT {
@Override
public int calculate(int a, int b) {
return a - b;
}
},
MULTIPLY {
@Override
public int calculate(int a, int b) {
return a * b;
}
};
}
// 测试
public class EnumInterfaceTest {
public static void main(String[] args) {
System.out.println(Calculator.ADD.calculate(5, 3)); // 8
System.out.println(Calculator.SUBTRACT.calculate(5, 3)); // 2
}
}
三、枚举单例:最安全的单例模式
用枚举实现单例,天然避免反射破坏、序列化问题,代码极简且万无一失(Effective Java推荐方案)。
java
public enum Singleton {
// 唯一实例
INSTANCE;
// 单例的业务方法
public void doSomething() {
System.out.println("枚举单例执行操作~");
}
}
// 测试
public class SingletonTest {
public static void main(String[] args) {
Singleton instance1 = Singleton.INSTANCE;
Singleton instance2 = Singleton.INSTANCE;
System.out.println(instance1 == instance2); // true(同一实例)
instance1.doSomething();
}
}
四、避坑点:枚举的"小脾气"
-
枚举项必须放在第一行,否则编译报错;
-
枚举不能继承其他类(已隐式继承Enum),但可实现多个接口;
-
values()方法是编译器自动生成的(Enum类没有),返回所有枚举项数组;
-
枚举的equals()已重写为==,无需手动实现。
总结
别再把枚举当"高级常量"用了------它是兼具类型安全、扩展性的特殊类,不管是状态管理、规则定义还是单例实现,都能玩出花。学会这些,你的Java代码会更优雅、更健壮~