Sun Blog

Back

枚举的本质Blur image

1. 枚举的基本使用#

枚举使用 enum 这个关键字来定义,例如为了表示衣服的尺寸定义一个枚举类型 Size

public enum Size {
    SMALL, MEDIUM, LARGE
}
java

Size 包括三个值,分别表示小、中、大,值一般是大写字母,多个值之间以逗号分隔

可以这样使用 Size

Size size = Size.MEDIUM;
java

Size size 声明了一个变量 size,它的类型是 Sizesize=Size.MEDIUM 将枚举值 MEDIUM 赋值给 size 变量

枚举变量的 toString() 方法返回其字面值,枚举类型还有一个 name() 方法也返回其字面值

Size size = Size.MEDIUM;
System.out.println(size.toString());
System.out.println(size.name());
java

输出

MEDIUM
MEDIUM
java

枚举值可以使用 equals()​​ 方法和 ==​​ 进行比较,结果相同

Size size = Size.MEDIUM;
System.out.println(size == Size.MEDIUM);
System.out.println(size == Size.LARGE);
System.out.println(size.equals(Size.MEDIUM));
java

输出为

true
false
true
java

枚举类型都有一个方法 int ordinal(),返回枚举值在声明时的顺序,从 0 开始

Size s0 = Size.SMALL;
Size s1 = Size.MEDIUM;
Size s2 = Size.LARGE;
System.out.println(s0.ordinal());
System.out.println(s1.ordinal());
System.out.println(s2.ordinal());
java

输出为

0
1
2
java

枚举类型都实现了 Comparable 接口,可以通过方法 compareTo​​ 与其他枚举值进行比较,其实就是比较 ordinal()​​ 方法返回值的大小

Size s0 = Size.SMALL;
System.out.println(s0.compareTo(Size.MEDIUM));
java

输出 -1 表明 SMALL ​小于 MEDIUM

枚举变量可以用于方法参数、类变量、实例变量等,最常用的还是用于 switch 语句

Size s0 = Size.SMALL;
switch (s0){
	case SMALL:
		System.out.println("chose small");
		break;
	case MEDIUM:
		System.out.println("chose medium");
		break;
	case LARGE:
		System.out.println("chose large");
		break;
}
java

注意在 switch ​语句内部,枚举值不能带枚举类型前缀,例如,直接使用 SMALL,不能使用 Size.SMALL

枚举类型还有一个静态方法 values() 返回一个包含所有枚举值的数组,顺序和声明时的顺序一致

for (Size size : Size.values()) {
	System.out.println(size);
}
java

输出

SMALL
MEDIUM
LARGE
java

2. 枚举的好处#

  • 定义枚举的语法更为简洁
  • 枚举更为安全。一个枚举类型的变量,它的值要么为 null,要么为枚举值之一,不可能为其他值,但使用整型变量,它的值就没有办法强制,值可能就是无效的。
  • 枚举类型自带很多便利方法(如 valuesvalueOftoString ​等),易于使用。

3. 枚举的底层原理#

枚举类型实际上会被 Java 编译器转换成一个对应的类,这个类型继承了 java.lang.Enum​​ 类。

Enum 类有 nameordinal 两个实例变量,在构造方法中需要传递。

name()toString()ordinal()compareTo()equals() 方法都是由 Enum 类根据其实例变量 nameordinal 实现的。

values()valueOf() 方法是编译器给每个枚举类型自动添加的。

编译器转换后的代码大致如下

public final class Size extends Enum {
    public static final Size SMALL = new Size("SMALL",0);
    public static final Size MEDIUM = new Size("MEDIUM",1);
    public static final Size LARGE = new Size("LARGE",2);
    private static final Size[] VALUES = new Size[]{SMALL,MEDIUM,LARGE};
    private Size(String name, int ordinal){
        super(name, ordinal);
    }
    public static Size[] values(){
        Size[] values = new Size[VALUES.length];
        System.arraycopy(VALUES, 0, values, 0, VALUES.length);
        return values;
    }
    public static Size valueOf(String name){
        return Enum.valueOf(Size.class, name);
    }
}
java

Sizefinal 的,所以枚举类型不能被继承,枚举值也都是 final 的,所以定义出来了就不能被修改

4. 更多使用场景#

实际使用时枚举中可能会有关联的实例变量和方法,例如

public enum Size {
    SMALL("S", "小号"), 
    MEDIUM("M", "中号"), 
    LARGE("L", "大号"),
    ;

    private String abbr;
    private String title;

    private Size(String abbr, String title) {
        this.abbr = abbr;
        this.title = title;
    }

    public String getAbbr() {
        return abbr;
    }
    public String getTitle() {
        return title;
    }
}
java

上述代码定义了两个实例变量 abbrtitle,以及对应的 get 方法,分别表示缩写和中文名称;定义了一个私有构造方法,接受缩写和中文名称,每个枚举值在定义的时候都传递了对应的值。

注意: 枚举值的定义需要放在最上面,枚举值写完之后,要以分号 ; 结尾,然后才能写其他代码

枚举的本质
https://blog.csun.site/blog/2025-09-14-nature-of-enumeration
Author Sun Xin
Published at September 14, 2025
Comment seems to stuck. Try to refresh?✨