JavaSE5️⃣核心类 - 枚举(enum)
1、枚举
1.1、含义
维基百科
在数学和计算机科学理论中,一个集的枚举是指:
- 列出有穷序列集的所有成员的程序。
- 一种特定类型对象的计数。
这两种类型经常重叠,是一个被命名的整型常数的集合。
1.2、int 常量
在 Java 5 之前,可定义 int 常量来表示枚举。
示例:定义季节。
public class Season {
public static final int SPRING = 0;
public static final int SUMMER = 1;
public static final int AUTUMN = 2;
public static final int WINTER = 3;
}
class Main {
public static void doSomething(int season){
if (season == Season.SPRING) {
// ...
}
}
}
存在问题
- 安全性:编译器无法检查传入值的合法性(类型、范围)。
- 可读性:int 常量的输出结果是数字,无法表示常量的特点。
2、enum
Java 5+
枚举(enumeration):表示一组预定义的常量
- 使用关键字
enum
,定义不同的枚举类。 - 编译器能自动检查枚举类型、某个引用值是否属于枚举集合内。
2.1、语法
按以下顺序声明一个枚举类。
- 声明枚举类,可实现接口。
- 声明成员变量(如果需要)。
- 声明构造方法(如果需要)。
- 声明枚举成员。
- 使用
()
填写参数列表(若调用空参构造方法,可省略括号)。 - 使用
,
分隔多个枚举成员,使用;
结束常量声明。
- 使用
示例
-
定义枚举类:
public enum Season { SPRING(0, "春天"), SUMMER(1, "夏天"), AUTUMN(2, "秋天"), WINTER(3, "冬天"), ; public final int order; public final String value; Season(int order, String value) { this.order = order; this.value = value; } }
-
编译后相当于:
public final class Season extends Enum { public static final Season SPRING = new Season(0, "春天"); public static final Season SUMMER = new Season(1, "夏天"); public static final Season AUTUMN = new Season(2, "秋天"); public static final Season WINTER = new Season(3, "冬天"); public final int order; public final String value; private Season(int order, String value) { this.order = order; this.value = value; } }
2.2、特点
2.2.1、成员变量
Enum
定义的 2 个成员变量
- name:枚举成员的名称。
- ordinal:枚举成员的序号,即声明的位置顺序。
- 从 0 开始计数。
- 新增的枚举需要放在后面,避免影响前面枚举的序号。
2.2.2、引用类型
enum
的本质是class
,拥有类的特性。
- 继承:默认继承自
java.lang.Enum
,无法被继承。 - 实现:可实现一个或多个接口。
- 成员结构:除了枚举常量,
enum
可以定义类的其它结构。- 构造方法(默认
private
)- 私有化,避免外部实例化新的枚举类型。
- 若无显式定义构造方法,默认会生成无参构造方法。
- 成员变量:建议
final
,并通过构造器初始化。 - 成员方法等其它结构。
- 构造方法(默认
2.2.3、单实例
参考 👉 单例模式
- 每个实例在 JVM 中具有唯一实例。
- 只能通过预定义的方式创建,无法
new
创建。
2.3、相关 API
2.3.1、获取实例
-
values():以数组形式返回所有枚举成员实例。
Season[] seasons = Season.values(); // [SPRING, SUMMER, AUTUMN, WINTER]
-
valueOf():通过
name
获取指定枚举实例。-
Enum
的静态方法。 -
枚举类的静态方法。
Season s1 = Enum.valueOf(Season.class, "SPRING"); Season s2 = Season.valueOf("SPRING");
-
2.3.2、名称
-
name():返回枚举成员的名称。
String springName = Season.SPRING.name(); // SPRING
-
toString():默认返回
name
,可以重写以提高可读性。String springStr = Season.SPRING.toString(); // 默认 SPRING
使用
name()
获取名称,使用
toString()
获取描述。
2.3.3、序号
-
ordinal():返回枚举成员的序号。
int o1 = Season.SPRING.ordinal(); // 0 int o2 = Season.WINTER.ordinal(); // 3
-
compareTo():比较枚举成员的序号之差。
int dist = Season.SPRING.compareTo(Season.WINTER); // -3
2.4、相关操作
2.4.1、比较
enum
成员具有唯一实例,可直接使用==
比较。也可使用
equals()
。
public void doSomething(Season season) {
if (season.equals(Season.SPRING)) { // ok
}
if (season == Season.SPRING) { // ok!
}
}
2.4.2、switch 枚举
随着 Java 5 引入
enum
类型,
switch
结构也支持判断枚举类型。
public void doSomething(Season season){
switch(season) {
case SPRING:
// ...
break;
case SUMMER:
// ...
break;
case AUTUMN:
// ...
break;
case WINTER:
// ...
break;
default:
// ...
}
}
原理:👉 编译期优化 1.7.2
- 生成一个合成类,包含一个成员变量(
int[]
数组)。- 数组元素与枚举成员的
ordinal
依次对应。- switch 枚举等价转换成 switch ordinal。