更新时间:2021-01-28 来源:Enum枚举类型 浏览量:
Enum的全写是Enumeration,这个词的翻译是列举、逐条陈述、细目。在程序语言中,枚举类型是一种特殊的数据类型(常用的数据类型比如字符串、整型),这种数据类型的变量值限定在固定的范围, 比如季节只有春夏秋冬,月份是12个。
在Java语言中, 枚举类型从JDK1.5才开始提供。在这之前使用接口静态常量来实现相关功能(也可以是类静态常量),以季节为例:
在不使用枚举类之前,一般使用接口静态常量实现。比如:
public interface Season {
public static final int SPRING = 1;
public static final int SUMMER = 2;
public static final int AUTUMN = 3;
public static final int WINTER = 4;
}
使用JUnit使用测试如下:
@Test
public void noEnum() {
int i = 1;
Assert.assertTrue(Season.SPRING==i);
}
使用接口静态常量的方式比较难限定变量的范围,而且定义繁琐,功能也很有限,于是在Java 1.5 中定义了一个枚举类型:java.lang.Enum
。
类似类(class)和接口(interface)的定义,Java提供enum关键字用来定义枚举类,在IDEA中创建枚举类的菜单如下:
<img src="Java枚举(Enum)类型的基本介绍与原理探求.assets/image-20200924184946393.png" alt="image-20200924184946393" style="zoom:50%;" />
同样定义一个季节的枚举类, 代码可以简洁如下:
package cn.osxm.jcodef.func.base;
public enum SeasonEnum {
SPRING, SUMMER, AUTUMN, WINTER
}
在枚举类中直接列出常量,常量遵循全部大写的规则。在上面的枚举类示例代码中,SPRING, SUMMER, AUTUMN, WINTER 是SeasonEnum的成员。
在JUnit使用测试如下:
@Test
public void enumBase() {
SeasonEnum season = SeasonEnum.SPRING;
Assert.assertTrue(season.equals(SeasonEnum.SPRING));
}
Java枚举类的特性有:
但是从上面SeasonEnum枚举类的定义来看,完全看不出这些特性,这些特性是怎么来的呢? 请看下面的原理探求。
ava枚举类型的奥秘就在编译阶段,枚举类在编译后会生成了一个扩展java.lang.Enum的类。这个可以通过JDK自带的javap工具来反编译生成的.class文件。对上面的生成的SeasonEnum.class文件进行反编译,因为这个文件的包路径是cn\osxm\jcodef\func\base,所以在命令行使用如下命令:
javap -p cn\osxm\jcodef\func\base\SeasonEnum.class
-p
参数的意思是反编译代码中包含私有的方法, p是private的意思。<img src="Java枚举(Enum)类型的基本介绍与原理探求.assets/image-20200924185250968.png" alt="image-20200924185250968" style="zoom:50%;" />
从控制台输出的反编译后的源码可以看出:
java.lang.Enum
类注意: 使用专门的Java反编译工具,比如JD GUI、luyten等对Eumn进行反编译的效果接近源码的效果,无法看到继承等特性,JD-GUI反编译的效果和源码时一致的,这也说明使用JD GUI来进行实际的反编译还是不错的。