1. 枚举的基本使用#
枚举使用 enum 这个关键字来定义,例如为了表示衣服的尺寸定义一个枚举类型 Size
public enum Size {
SMALL, MEDIUM, LARGE
}javaSize 包括三个值,分别表示小、中、大,值一般是大写字母,多个值之间以逗号分隔
可以这样使用 Size
Size size = Size.MEDIUM;javaSize size 声明了一个变量 size,它的类型是 Size,size=Size.MEDIUM 将枚举值 MEDIUM 赋值给 size 变量
枚举变量的 toString() 方法返回其字面值,枚举类型还有一个 name() 方法也返回其字面值
Size size = Size.MEDIUM;
System.out.println(size.toString());
System.out.println(size.name());java输出
MEDIUM
MEDIUMjava枚举值可以使用 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
truejava枚举类型都有一个方法 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
2java枚举类型都实现了 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
LARGEjava2. 枚举的好处#
- 定义枚举的语法更为简洁
- 枚举更为安全。一个枚举类型的变量,它的值要么为
null,要么为枚举值之一,不可能为其他值,但使用整型变量,它的值就没有办法强制,值可能就是无效的。 - 枚举类型自带很多便利方法(如
values、valueOf、toString等),易于使用。
3. 枚举的底层原理#
枚举类型实际上会被 Java 编译器转换成一个对应的类,这个类型继承了 java.lang.Enum 类。
Enum 类有 name 和 ordinal 两个实例变量,在构造方法中需要传递。
name()、toString()、ordinal()、compareTo()、equals() 方法都是由 Enum 类根据其实例变量 name 和 ordinal 实现的。
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);
}
}javaSize 是 final 的,所以枚举类型不能被继承,枚举值也都是 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上述代码定义了两个实例变量 abbr 和 title,以及对应的 get 方法,分别表示缩写和中文名称;定义了一个私有构造方法,接受缩写和中文名称,每个枚举值在定义的时候都传递了对应的值。
注意: 枚举值的定义需要放在最上面,枚举值写完之后,要以分号 ; 结尾,然后才能写其他代码