关于Java中枚举Enum的深入剖析
在编程语言中我们,都会接触到枚举类型,通常我们进行有穷的列举来实现一些限定。Java也不例外。Java中的枚举类型为Enum,本文将对枚举进行一些比较深入的剖析。
什么是Enum
Enum是自Java 5 引入的特性,用来方便Java开发者实现枚举应用。一个简单的Enum使用如下。
// ColorEnum.javapublic enum ColorEmun { RED, GREEN, YELLOW}public void setColorEnum(ColorEmun colorEnum) { //some code here}setColorEnum(ColorEmun.GREEN);
为什么会有Enum
在Enum之前的我们使用类似如下的代码实现枚举的功能.
public static final int COLOR_RED = 0;public static final int COLOR_GREEN = 1;public static final int COLOR_YELLOW = 2;public void setColor(int color) { //some code here}//调用setColor(COLOR_RED)
然而上面的还是有不尽完美的地方
- setColor(COLOR_RED)与setColor(0)效果一样,而后者可读性很差,但却可以正常运行
- setColor方法可以接受枚举之外的值,比如setColor(3),这种情况下程序可能出问题
概括而言,传统枚举有如下两个弊端
- 安全性
- 可读性,尤其是打印日志时
因此Java引入了Enum,使用Enum,我们实现上面的枚举就很简单了,而且还可以轻松避免传入非法值的风险.
枚举原理是什么
Java中Enum的本质其实是在编译时期转换成对应的类的形式。
首先,为了探究枚举的原理,我们先简单定义一个枚举类,这里以季节为例,类名为Season
,包含春夏秋冬四个枚举条目.
public enum Season { SPRING, SUMMER, AUTUMN, WINTER}
然后我们使用javac编译上面的类,得到class文件.
javac Season.java
然后,我们利用反编译的方法来看看字节码文件究竟是什么.这里使用的工具是javap的简单命令,先列举一下这个Season下的全部元素.
company javap SeasonWarning: Binary file Season contains com.company.SeasonCompiled from "Season.java"public final class com.company.Season extends java.lang.Enum<com.company.Season> { public static final com.company.Season SPRING; public static final com.company.Season SUMMER; public static final com.company.Season AUTUMN; public static final com.company.Season WINTER; public static com.company.Season[] values(); public static com.company.Season valueOf(java.lang.String); static {};}
从上反编译结果可知
- java代码中的Season转换成了继承自的java.lang.enum的类
- 既然隐式继承自java.lang.enum,也就意味java代码中,Season不能再继承其他的类
- Season被标记成了final,意味着它不能被继承
static代码块
使用javap具体反编译class文件,得到静态代码块相关的结果为
static {}; Code: 0: new