枚举(enumeration
,简写为 enum
)是一种特殊的类,用于表示一组有限的常量。它包含一组特定的、固定的对象。例如,表示季节时,我们可以定义一个枚举来表示春天、夏天、秋天和冬天。如果直接用类来实现季节,可能会出现不合理的情况,比如可以创建一个名字不符的实例,或者随意修改季节的名称,这显然不符合实际情况。因此,使用枚举可以有效解决这些问题。在 Java
中,常见的枚举实现方式有两种:一种是自定义类,另一种是使用 enum
关键字。使用 enum
关键字可以更简洁、更安全地定义常量集合,并限制只能使用预定义的值。
一、自定义类
在使用自定义类实现枚举时,可以先定义一个 Season
类,并在该类中添加一个 name
属性,用于表示季节的名称。同时,我们还需要提供构造方法以及 getter 和 setter 方法来访问和修改这个属性。以下是示例代码:
class Season {private String name;public Season(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
然而,通过分析季节的需求,我们发现之前的类定义无法满足固定取值和只读的要求,因为通过 setter 方法可以随意添加和修改季节名称。因此,我们需要对类的定义进行修改。创建自定义枚举类的步骤包括:
- 将构造器私有化,防止直接
new
; - 删除
setName()
方法,防止属性被修改; - 在
Season
内部直接创建固定对象,通过static
修饰符对外暴露对象; - 添加
final
修饰符,优化底层。
注意:枚举对象名通常使用全部大写(常量的命名规范)。
public class Season {private String name;public static final Season SPRING = new Season("春天");public static final Season SUMMER = new Season("夏天");public static final Season AUTUMN = new Season("秋天");public static final Season WINTER = new Season("冬天");private Season(String name) {this.name = name;}}
二、使用 enum
关键字
与自定义类的步骤不同,使用enum
关键字实现枚举的步骤包括:
- 使用
enum
替代class
; - 将构造器私有化;
- 直接使用
常量名(实参列表)
,若有多个常量对象,使用,
间隔,若使用无参构造器,则实参列表和小括号都可省略; - 枚举对象必须放在枚举类的首行。
public enum Season {SPRING("春天"), SUMMER("夏天"), AUTUMN("秋天"), WINTER("冬天");private String name;private Season(String name) {this.name = name;}
}// 使用时
System.out.println(Season.SPRING);
注意:枚举类的构造器总是私有,可以省略
private
修饰符。如果声明一个enum
构造器为public
或protected
,则会出现语法错误。另外,枚举类和普通类一样,可以实现接口,形式为enum 类名 implements 接口1,接口2{}
。
三、enum
常用方法
// 源码定义
public abstract class Enum<E extends Enum<E>>implements Constable, Comparable<E>, Serializable {}
从源码定义来看,当使用 enum
关键字定义一个枚举类时,该枚举类会隐式继承自抽象类 Enum
。而 Enum
抽象类实现了多个接口,因此,enum
类可以使用 Enum
类提供的相关方法。常见的方法如下表所示。
方法名 | 描述 | 实例 |
---|---|---|
static Enum valueOf(Class enumClass, String name) | 返回给定类中有指定名字的枚举常量 | Season season = Enum.valueOf(Season.class, "SPRING"); |
String toString() | 返回枚举常量名 | Season.SPRING.toString() |
int ordinal() | 返回枚举常量在 enum 声明中的位置,从 0 开始计数 | Season.SPRING.ordinal() |
E[] values() | 返回定义的所有枚举常量 | Season[] seasons = Season.values() |
int compareTo(E other) | 若枚举常量位置出现在 other 之前,则返回负整数;如果 this == other ,则返回 0 ;否则,返回正整数 | season0.compareTo(season1) |
final boolean equals(E other) | 比较两个枚举常量是否相等(也可以用== ) | season0.equals(season1) |
注意:使用
enum
关键字后,就不能再继承其它类了,因为enum
会隐式继承Enum
,而Java
是单继承机制。