枚举
Java的枚举类型,关键字enum,全称为 enumeration,从Java 5.0 开始提供了的一种新类型。
示例
public enum EnumTest {
FIRST, SECOND, THIRD, FOURTH, FIFTH;
}
通过enum关键字命名,内部写枚举变量。
反编译
注意:这里使用的反编译工具在资料中单独提供,常规的反编译工具会直接反编译为enum。
enum 的语法结构尽管和 class 的语法不一样,但是经过编译器编译之后产生的是一个class文件。该class文件经过反编译可以看到实际上是生成了一个类,该类继承了java.lang.Enum<E>。
public final class EnumTest extends Enum
{
//返回存储枚举实例的数组的副本。values()方法通常用于foreach循环遍历枚举常量。
public static EnumTest[] values()
{
return (EnumTest[])$VALUES.clone();
}
//根据实例名获取实例
public static EnumTest valueOf(String name)
{
return (EnumTest)Enum.valueOf(com/boxuegu/intermediate/language/sugar/enumtest/EnumTest, name);
}
//私有构造方法,这里调用了父类的构造方法,其中参数s对应了常量名,参数i代表枚举的一个顺序(这个顺序与枚举的声明顺序对应,用于oridinal()方法返回顺序值)
private EnumTest(String s, int i)
{
super(s, i);
}
//我们定义的枚举,在这里声明了五个EnumTest的常量对象引用,对象的实例化在static静态块中
public static final EnumTest FIRST;
public static final EnumTest SECOND;
public static final EnumTest THIRD;
public static final EnumTest FOURTH;
public static final EnumTest FIFTH;
//将所有枚举的实例存放在数组中
private static final EnumTest $VALUES[];
static
{
//实例化常量对象
FIRST = new EnumTest("FIRST", 0);
SECOND = new EnumTest("SECOND", 1);
THIRD = new EnumTest("THIRD", 2);
FOURTH = new EnumTest("FOURTH", 3);
FIFTH = new EnumTest("FIFTH", 4);
//将所有枚举的实例存放在数组中
$VALUES = (new EnumTest[] {
FIRST, SECOND, THIRD, FOURTH, FIFTH
});
}
}
深入理解枚举
-
枚举的父类
通过上面的反编译后代码,我们可以看到
public final class EnumTest extends Enum
,说明该类是继承了Enum类的,同时final关键字告诉我们,这个类是不能被继承的。当我们使用enmu来定义一个枚举类型的时候,编译器会自动帮我们创建一个final类型的类继承Enum类,所以枚举类型不能被继承。 -
构造方法
私有构造方法,这里调用了父类的构造方法
protected Enum(String name, int ordinal)
,其中参数s对应了常量名name,参数i代表枚举的一个顺序ordinal,这个顺序与枚举的声明顺序对应,用于oridinal()方法返回顺序值。 -
常量对象
我们定义的枚举类型在反编译后的代码中,对应了五个EnumTest的常量对象引用。
这五个对象使用static静态块中的方式进行实例化,
FIRST = new EnumTest("FIRST", 0);
,可以看到使用了私有构造方法进行了实例化,每个值的名称都被转换成一个字符串,而顺序就是我们定义枚举的声明顺序(从0开始)。
使用场景
可以替代常量类,在没有枚举之前,一般使用如下形式定义一些常量:
public interface Order {
String FIRST = "FIRST";
String SECOND = "SECOND";
String THIRD = "THIRD";
String FOURTH = "FOURTH";
}
枚举扩展(自定义属性和方法)
既然enum枚举类型在经过编译器后,被编译成了一个普通类, 那么可以把 enum 看成是一个普通的 class,于是我们可以对其定义一些属性和方法,不同之处是:enum 不能使用 extends 关键字继承其他类,因为 enum 已经继承了 java.lang.Enum(java是单一继承)。
public enum EnumTest2 {
FIRST(1), SECOND(2), THIRD(3), FOURTH(4), FIFTH(5);
private int value;
/**
* 带一个参数的构造函数
*
* @param value
*/
private EnumTest2(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static void main(String[] args) {
System.out.println("EnumTest.FRI 的 value = " + EnumTest2.FIRST.getValue());
}
}
枚举对象的常用方法介绍
int compareTo(E o)
比较此枚举与指定对象的顺序。
Class<E> getDeclaringClass()
返回与此枚举常量的枚举类型相对应的 Class 对象。
String name()
返回此枚举常量的名称,在其枚举声明中对其进行声明。
int
ordinal()`
返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。
String toString()
返回枚举常量的名称,它包含在声明中。
static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)
返回带指定名称的指定枚举类型的枚举常量。
网友评论