您的位置 首页 java

Java中的枚举类型(Enum)详解

欢迎关注我们,不错过每期的原创干货!


1 枚举类型 初探

枚举类型,其语法总让人觉着怪怪的,如下:

简单的一行,就定义了包含四个值的枚举类型,缺总让人觉着语法有点怪异。而在使用时:

就可以得到输出:

那我们简单的一行定义中,到底发生了什么?枚举类型在编译时是怎样实现的?它还有着怎样的特点?

我们将会分几节对 java 中的枚举类型进行介绍。

2 枚举产生之前

如果不使用枚举,我们要对“春夏秋冬”这四个值分别赋予一个数字,则常见的操作为:

上述方法定义十分繁琐,而且容易出错。例如我们定义的int数字出现重复,编译器也不会给出任何的警示。同时,这样的操作是实在太频繁了,最终Java 5中增加了枚举类型。

而是用枚举类型后,一切就变成了如下所示的简单几行:

而且,Java自动给按照 枚举值 出现的顺序,从0开始分配了编号。通过name()可以获得枚举值的名称,通过ordinal()可以获得枚举值的编号。

3 枚举实现原理

那我们定义枚举类型后,到底发生了什么呢?我们对枚举的实现原理进行探究。

首先,我们在实现Season枚举类时,并没有定义name()和ordinal()方法。我们从这里入手,点击该方法后,发现进入了一个 抽象类

并且,我们发现编译器不允许我们自行实现该抽象类从而构造一个新的类。但是,既然我们的Season枚举类可以调用其中的方法,因此Season枚举类应该是继承了该抽象类。

为了验证这一猜想,我们让Season类继承一个其他的类,发现果然不可以,因为Java是不允许多继承的。

具体,我们对Season类进行 反编译 ,即:java -p Season.class,得到反编译后的结果:

我们看到,对与枚举类,有很多值的注意的点:

  • 枚举类在经过编译后确实是生成了一个扩展了java.lang.Enum的类
  • 枚举类是final的,因此我们无法再继承它了
  • 我们定义的每个枚举值都是该类中的一个成员,且成员的类型仍然是Season类型
  • 枚举类中被默认增加了许多 静态方法 ,例如values()等

为了进一步了解每个方法中的操作,我们使用java -p -c Season.class每个方法中的 字节码

根据字节码,我们还原其操作代码,大致如下:

注意:以下代码为笔者自己翻译,如果有好的字节码查看工具请一定要留言告诉我啊。

通过这里我们可以看到,在类的static操作中,编译器帮助我们生成每个枚举值的对象。

4 总结

我们在总结一下,我们使用enum定义的枚举类型,会在编译之后转化为一个继承了java .lang.Enum的类,而我们定义的每个枚举值都会在类的初始化阶段被 实例化 为我们所定义的枚举类的一个对象。

同时,编译器还帮我们在类中增加了两个方法,分别是:values()和valueOf()。

至此,我们对Java的枚举对象有了彻底的认识。

但是,我们依旧有着很多的疑惑:

  • 编译器插入的方法和正常的方法有无不同
  • 枚举类型还有哪些使用上的注意点,例如相关方法和操作
  • 枚举类型的实现上还有哪些特殊之处

这些,我们在接下来的文章中继续分析。

—END—

欢迎关注我们,不错过每期的原创干货!

文章来源:智云一二三科技

文章标题:Java中的枚举类型(Enum)详解

文章地址:https://www.zhihuclub.com/194397.shtml

关于作者: 智云科技

热门文章

网站地图