浅谈Java之枚举

使用关键字 enum 可以定义枚举类型,枚举类型可以包含一组序列集,可以作为常规的程序组件使用。当我们需要从固定的序列中获取值时,使用枚举类型是一个很好的方式。

基本特性

尽管 enum 看起来像是一个新的数据类型,但是这个关键字只是为 enum 生成对应的类时,产生某些编译器行为。 可以将 enum 当做其他任何类来处理。

创建 enum 时,编译器会自动生成一个对应的类,这个类会继承 java.lang.Enum

由此可知,枚举类型具有以下 特性

  • enum 不能再继承。
  • enum 可以使用 Enum类 的方法。
  • enum 除了不能继承以外,基本可以看做一个常规的类。

除此之外,枚举类型还具有以下 特性

  • enum 也不能被继承。
  • enum 内可以定义一些序列,这些值实际上enum实例,默认是 public static final
  • enum 需要提供和实例声明对应的构造函数,enum构造函数默认是 private
1
2
3
4
5
package tk.gushizone.java.basic.enumeration;

public enum SimpleEnum {
SUCCESS, WARNING, ERROR;
}
继承于 Enum的方法 说明
ordinal() 返回 enum实例 在声明时的次序。
name() 返回 enum实例 在声明时的名字。
toString() 默认与 name() 相同。
getDeclaringClass() 获取 enum实例 所属的类类型。
1
2
3
4
5
6
7
System.out.println(SimpleEnum.SUCCESS.ordinal());
System.out.println(SimpleEnum.SUCCESS == SimpleEnum.SUCCESS);

System.out.println(SimpleEnum.WARNING.name());
System.out.println(SimpleEnum.WARNING.toString());

System.out.println(SimpleEnum.ERROR.getDeclaringClass());
1
2
3
4
5
0
true
WARNING
WARNING
class tk.gushizone.java.basic.enumeration.SimpleEnum

name() 方法对应,也可以通过枚举的名字获取枚举类型。

方法 说明
valueOf(Class<T> enumType, String name) 通过枚举的名字获取枚举类型,可被继承的 static 方法。
valueOf(String name) 通过枚举的名字获取枚举类型,由编译器添加。
1
2
3
4
System.out.println(Enum.valueOf(SimpleEnum.class, "ERROR") == SimpleEnum.ERROR);
System.out.println(SimpleEnum.valueOf(SimpleEnum.class, "ERROR") == SimpleEnum.ERROR);

System.out.println(SimpleEnum.valueOf("ERROR") == SimpleEnum.ERROR);
1
2
3
true
true
true

添加属性和方法

一般枚举会用来定义数据字典,为了增加可用性,我们可以向枚举类型中添加属性和方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package tk.gushizone.java.basic.enumeration;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum DictCode {

SUCCESS("0", "成功"),

WARNING("1", "警告"),

ERROR("-1", "错误");

private String code;

private String codeName;
}

需要注意的是:

  • 向枚举中添加属性和方法后,实例声明一定要使用 ; 结尾。

    虽然当enum中只有实例时可以省略 ; 的 ,但不推荐。

  • 实例声明实际上会调用构造方法,故需要提供对应的构造方法。

解析 values()

enum 提供了一个遍历的方法 values()

1
2
3
for (DictCode item : DictCode.values()) {
System.out.println(item.name() + ": " + item.getCodeName() + item.getCode());
}
1
2
3
SUCCESS: 成功0
WARNING: 警告1
ERROR: 错误-1

实际上, values() 是编译器添加的静态方法,而不是继承自Enum。

如果我们想遍历Enum可以使用 Class类 的 getEnumConstants() 方法。

因为该方法来自 Class类,故也可用在没枚举类型上,但会报空指针异常。

1
2
3
4
5
6
7
8
Enum e = DictCode.SUCCESS;
// Enum.values(); // Cannot resolve method 'values()'
// e.values(); // Cannot resolve method 'values()'

for (Enum enumConstant : e.getClass().getEnumConstants()) {
DictCode item = (DictCode) enumConstant;
System.out.println(item.name() + ": " + item.getCodeName() + item.getCode());
}
1
2
3
SUCCESS: 成功0
WARNING: 警告1
ERROR: 错误-1