枚举类
枚举类型本质上也是一种类,只不过是这个类的对象是有限个,不能让用户随意创建。
经典声明
在JDK5声明一个枚举类:
java
public class Color {
// 1. 定义常量对象
public static final Color RED = new Color("RED");
public static final Color GREEN = new Color("GREEN");
public static final Color BLUE = new Color("BLUE");
// 2. 属性
private String name;
// 3. 构造方法私有化(防止外部 new)
private Color(String name) {
this.name = name;
}
// 4. 提供 getter
public String getName() {
return name;
}
// 5. toString(可选)
@Override
public String toString() {
return name;
}
}构造方法必须是 private
java
private Color(String name)- 防止外部创建新对象,保证枚举值是固定的
所有实例都是 public static final
java
public static final Color RED = new Color("RED");public:外部可访问static:类级别,全局唯一final:不能被修改引用
控制实例数量
整个类中只有这几个对象:
java
RED / GREEN / BLUEenum声明枚举类
枚举类的常量对象列表必须在枚举类的首行,因为是常量,所以建议大写。
枚举类默认继承的是
java.lang.Enum类,因此不能再继承其他的类型。枚举对象使用
,分隔,如果常量对象列表后面没有其他代码,那么;可以省略,否则不可以省略;
java
public enum Status {
ACTIVE, INACTIVE, PENDING, REJECTED
}java
package org.example;
public enum Season {
SPRING("春天", "温暖"),
SUMMER("夏天", "炎热"),
AUTUMN("秋天", "凉爽"),
WINTER("冬天", "寒冷");
private final String name;
private final String desc;
Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
}使用枚举类
java
public class EnumIfExample {
public static void main(String[] args) {
Season season = Season.SPRING;
if (season == Season.SPRING) {
System.out.println("春天来了,万物复苏!");
} else if (season == Season.SUMMER) {
System.out.println("夏天炎热,适合游泳。");
} else if (season == Season.AUTUMN) {
System.out.println("秋天收获的季节。");
} else if (season == Season.WINTER) {
System.out.println("冬天寒冷,要注意保暖。");
}
// 遍历所有枚举值
System.out.println("所有季节:");
for (Season s : Season.values()) {
System.out.println(s);
}
// 根据字符串获取枚举值
String seasonName = "WINTER";
Season s2 = Season.valueOf(seasonName);
System.out.println("从字符串获取的季节: " + s2);
}
}Enum类
toString
java
public String toString()Enum重写了toString方法:默认返回的是常量名(对象名,value),可以继续手动重写该方法
java
System.out.println(Season.SPRING);//SPRINGstatic values
java
static 枚举类型[] values()被子类重写:返回所有枚举成员组成的数组。
java
for (Season s : Season.values()) {
System.out.println(s);
}
//SPRING
//SUMMER
//AUTUMN
//WINTERstatic valueOf
java
static 枚举类型 valueOf(String name)被子类重写:可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常IllegalArgumentException。
java
Season spring = Season.valueOf("SPRING");
System.out.println(spring);name
得到当前枚举常量的名称
java
public final String name()java
System.out.println(Season.SPRING.name());//SPRINGordinal
返回枚举变量的定义顺序,顺序从0开始
java
public final int ordinal()java
System.out.println(Season.valueOf("SUMMER").ordinal());//1枚举类编译
枚举常量初始化
枚举类的常量对象列表系统会自动添加
public static final修饰。编译器会自动向构造函数传入
name,ordinal
java
enum Season {
SPRING, SUMMER, AUTUMN, WINTER
}java
public static final Season SPRING = new Season("SPRING", 0);
public static final Season SUMMER = new Season("SUMMER", 1);
public static final Season AUTUMN = new Season("AUTUMN", 2);
public static final Season WINTER = new Season("WINTER", 3);构造方法
默认生成构造方法:
java
private Season(String name, int ordinal) {
super(name, ordinal);
}我们也可以自己添加构造方法,构造方法的 private 可以省略
java
public enum Season {
SPRING("春天", "温暖"),
SUMMER("夏天", "炎热"),
AUTUMN("秋天", "凉爽"),
WINTER("冬天", "寒冷");
private final String name;
private final String desc;
Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
}java
public final class Season extends Enum<Season> {
public static final Season SPRING = new Season("SPRING", 0, "春天", "温暖");
public static final Season SUMMER = new Season("SUMMER", 1, "夏天", "炎热");
public static final Season AUTUMN = new Season("AUTUMN", 2, "秋天", "凉爽");
public static final Season WINTER = new Season("WINTER", 3, "冬天", "寒冷");
private final String name;
private final String desc;
private Season(String enumName, int ordinal, String name, String desc) {
super(enumName, ordinal); // 👈 关键:传给 Enum
this.name = name;
this.desc = desc;
}
}重写方法
编译器自动为我们重写了父类Enum的values和valueOf方法
- values
java
public static Season[] values() {
return new Season[]{SPRING, SUMMER, AUTUMN, WINTER};
}- valueOf
java
public static Season valueOf(String name) {
return Enum.valueOf(Season.class, name);
}switch与枚举
当 switch 的表达式是一个枚举类型时,case 标签中不需要写枚举类名,直接写枚举常量即可。
java
Season season = Season.SPRING;
switch (season) {
case SPRING:
System.out.println("春天");
break;
case SUMMER:
System.out.println("夏天");
break;
case AUTUMN:
System.out.println("秋天");
break;
case WINTER:
System.out.println("冬天");
break;
}枚举实现接口
- 所有枚举值共享同一个实现
java
public enum Season implements SeasonBehavior {
SPRING, SUMMER, AUTUMN, WINTER;
@Override
public String getDesc() {
return "默认描述";
}
}- 每个枚举不同实现
java
public enum Season implements SeasonBehavior {
SPRING("春天", "温暖") {
@Override
public String getDesc() {
return name + ",万物复苏";
}
},
SUMMER("夏天", "炎热") {
@Override
public String getDesc() {
return name + ",很热";
}
},
AUTUMN("秋天", "凉爽") {
@Override
public String getDesc() {
return name + ",适合出游";
}
},
WINTER("冬天", "寒冷") {
@Override
public String getDesc() {
return name + ",要穿羽绒服";
}
};
protected final String name;
protected final String climate;
Season(String name, String climate) {
this.name = name;
this.climate = climate;
}
}比 switch更加优雅:
java
String desc = switch (season) {
case SPRING -> "春天";
case SUMMER -> "夏天";
case AUTUMN -> "秋天";
case WINTER -> "冬天";
};HowToUse
选择 常量还是枚举,取决于你业务的复杂度和可维护性:
- 简单值判断 → 常量够用。
- 逻辑复杂、有扩展性 → 枚举更好。
