在Java中可以使用enum
来定义一个枚举类。枚举类属于类,是一种特殊的类。
enum类的基类
enum还有基类?是的!每一个enum类都默认有一个基类java.lang.Enum
,通过javap -v
反编译enum类的class文件可以得到验证:
> javap -v com.company.TestEnum
Classfile /C:/Users/gyb_c/IdeaProjects/test/out/production/test/com/company/TestEnum.class
Last modified 2021年4月13日; size 1138 bytes
MD5 checksum 751db34bacc2a6d98137da3a8b29a559
Compiled from "TestEnum.java"
public final class com.company.TestEnum extends java.lang.Enum<com.company.TestEnum>
public final class com.company.TestEnum extends java.lang.Enum<com.company.TestEnum>
从这段代码可以查看出两点:
- 定义的枚举类在编译之后就是一个普通最终类(class和final关键字)(是不是可以认为Java中的enum类是一个语法糖?)
- 默认继承
java.lang.Enum
类
关于java.lang.Enum
类
类定义:
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
从类的定义可以看出:
- 它是一个抽象类
- 支持泛型,类型必须是
Enum
的子类 - 实现了
Comparable<E>
,Serializable
接口
有用的方法
构造方法:
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
每一个enum类都默认有两个属性name
和ordinal
,name
表示枚举常量的名字,ordinal
表示枚举常量的编号(从0开始编号)。
/**
* 返回枚举常量的名字
*/
public final String name() {
return name;
}
/**
* 返回枚举常量的编号
*/
public final int ordinal() {
return ordinal;
}
/**
* 等同于name()方法,但子类可以覆盖实现
*/
public String toString() {
return name;
}
/**
* 静态方法,根据枚举类的class和枚举常量名获取枚举常量
*/
public static <T extends Enum<T>> T valueOf(Class<T> enumType,String name) {
//省略实现....
}
enum类的特性
下面是一个enum类:
public enum TestEnum {
A(1), B(2), C(3);
private final int code;
TestEnum(int code) {
this.code = code;
}
public int getCode() {
return code;
}
}
其中A
,B
,C
叫做枚举常量,每个枚举常量用,
分开。如果enum类有有参构造函数,则需要传参。
- 每一个枚举常量都是一个enum类的实例
- 每一个枚举常量都有一个编号(从0开始编号),通过
ordinal()
方法获取 - enum类如果有属性,必须显示定义有参构造函数,否则无法完成属性的赋值
- 构造函数必须是私有的(private修饰),但
private
可以不写,默认就是私有的 - enum类无法通过
new
进行实例化(构造函数是私有的) - enum类自带一个静态
values()
方法,该方法返回该类定义的枚举常量数组(该方法是由编译器添加的 static 方法,在源码中看不到,可以通过反编译class看到) - enum类编译后就是一个继承于
java.lang.enum
类的用final
标记的普通类 - enum类可以定义普通方法
- enum类不能显示继承任何类(java使用单继承,而enum类默认继承Enum类),但可以实现接口
- 在switch语句中可以使用枚举
打印枚举常量的名字和编号:
public class EnumMain {
public static void main(String[] args) {
TestEnum[] values = TestEnum.values();
for (TestEnum value : values) {
System.out.println(value.name()+"->"+value.ordinal()+"->"+value.getCode());
}
}
}
输出:
A->0->1
B->1->2
C->2->3