首页 > 编程语言 >java enum枚举实现机制

java enum枚举实现机制

时间:2024-01-27 13:33:40浏览次数:35  
标签:enum java Season Enum 编译器 枚举 抽象类 方法

在上篇文章中,我们对Java中的枚举类进行了详细的介绍。

对于Enum还不了解的小伙伴,可以先预习《Java中的枚举类型(Enum)详解》一文。

通过反编译,我们知道Java枚举类会在编译之后转化为一个继承了java

.lang.Enum的类,而我们定义的每个枚举值都会在类的初始化阶段被实例化为我们所定义的枚举类的一个对象。

在枚举类被编译之后,有一些方法是编译器在编译阶段写入的,那这些方法有什么特点?枚举类中还有一些继承来的方法,它们又有哪些?枚举类中的枚举值是在编译阶段被创建为对象,那构造函数又在哪?

这篇文章我们将详细分析。

1 Enum抽象类常见方法

我们上篇文章已经讲过,枚举类实际上继承了Enum抽象类,因此Enum抽象类是所有枚举类型的基本类,下面是它的常见方法:

  • ordinal()方法:该方法获取的是枚举变量在枚举类中声明的顺序,下标从0开始,如日期中的MONDAY在第一个位置,那么MONDAY的ordinal值就是0,如果MONDAY的声明位置发生变化,那么ordinal方法获取到的值也随之变化,注意在大多数情况下我们都不应该首先使用该方法,毕竟它总是变幻莫测的。
  • compareTo(E o)方法:则是比较枚举的大小,注意其内部实现是根据每个枚举的ordinal值大小进行比较的。
  • name()方法与toString():几乎是等同的,都是输出变量的字符串形式。
  • getDeclaringClass(): 返回该枚举变量所在的枚举类。

需要再次说明的是,以上的方法都是Enum抽象类的方法,会被Enum的对象继承,而不是Enum的静态方法。而最终枚举值被实例化成了Enum对象,所以,枚举值拥有以上的方法。

这一块比较简单,我们直接举例子说明:

首先我们定义一个最简单的枚举类:

之后我们在定义一个附带属性的枚举类:

接下来,我们写方法进行试验:

最后结果:

我们可以看到,对于每个枚举值,可以调用上述的继承自Enum抽象类的方法。

2 枚举类型的构造函数

既然枚举值是由编译器创建为枚举类型的实例,那它必然调用了构造函数。那该函数在哪呢?我们能不能调用呢?

其实该构造函数也在Enum抽象类中。

 

我们特意将方法注释也保留了下来,可以看到,该方法只能由编译器调用,开发人员无法调用。所以说,我们还是不要操心了,只需要定义好枚举类型,剩下的交给编译器。

3 再论编译器插入的静态方法

我们知道values()方法和valueOf(String s)方法是由编译器插入到枚举类中的静态方法。这总让人觉得怪异。而同时,我们知道枚举类型中的每一个枚举值也在编译阶段被声明为了一个枚举类。关于这几点,我们在上一篇文章中已经详细分析,大家可以回上篇文章找回记忆。我们直接贴出通过字节码推出的代码,如下:

有人会这么认为:

  • 原来的Season枚举类中被编译器插入了values()方法和valueOf(String s)方法,因此能够正常调用Season.values()
  • 如果我们使用某个枚举值,如Season.AUTUMN向上转型成为Season枚举类,则无法调用values()方法和valueOf(String s)方法

其实这是不对的,因为无论是原生的Season枚举类还是Season.AUTUMN向上转型成的Season枚举类,本质上是同一个枚举类。因此,都应该可以调用values()方法和valueOf(String s)方法。

对此,我们进行验证:

得到如下输出:

证明了笔者的猜测。

4 总结

通过该文章,我们对枚举类中的方法进行了全面的了解:

  • 枚举类在编译阶段会被编译器插入一些静态方法
  • 枚举类本身有个只有编译器能够调用的构造方法,编译器会使用该方法将枚举值实例化为枚举类型的对象
  • 枚举值被实例化后,继承了众多java.lang.Enum中的方法

这样,通过《Java中的枚举类型(Enum)详解》和本篇文章,我们对枚举类型的原理和方法有了详细的了解。

转:https://zhuanlan.zhihu.com/p/64604609

 

jdk文档 enum抽象类:

https://www.runoob.com/manual/jdk11api/java.base/java/lang/Enum.html

public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
/**
* The name of this enum constant, as declared in the enum declaration.
* Most programmers should use the {@link #toString} method rather than
* accessing this field.
*/
private final String name;


public abstract class Enum<E extends Enum<E>>{
public final int compareTo( E o) { ... }
}

Enum的源码中<E extends Enum<E>>这种格式的泛型是指:
该类只能被子类实例化,子类会继承其方法.就是类型E是Enum的子类.而该类的compareTo方法参数就是类型E,既子类.

 

下面做个标志,方便理解

考虑下面的语法

E extends Foo<E>

首先,这是一个泛型,使用E作为类型参数。
其次,对于E有上界限制,即E必须是Foo<E>的子类。

E被识别为Foo的子类,这个情况相当于把一个子类或者自己当成参数,传入到自身,引起一些特别的语法效果,

详细见:

解读 Enum<E extends Enum<E>>

 

 

标签:enum,java,Season,Enum,编译器,枚举,抽象类,方法
From: https://www.cnblogs.com/youxin/p/17991342

相关文章

  • 初识JAVA的第4天,循环结构
    day4java新手随笔练习publicclassDoc{Stringname;//属性/***since指明需要最早使用的jak版本*@authorwushen作者名*@paramname参数名*@return返回值情况*@throwsException异常抛......
  • SpringBoot启动项目报错:java.lang.UnsatisfiedLinkError: D:\files\software\jdk-1
    目录问题描述解决方法:问题描述在运行向的时候出现报错:java.lang.UnsatisfiedLinkError:D:\files\software\jdk-15.0.1\jdk-17.0.3.1\bin\tcnative-1.dll:Can'tloadIA32-bit.dllonaAMD64-bitplatform atjava.base/jdk.internal.loader.NativeLibraries.load(Native......
  • windows下java启动失败
    windows下java启动失败一、问题现象微服务原来在linux下部署,现在有客户环境为windowsserver,把linux的包拷到windowsserver下,使用java-jar命令无法启动。同样的包在linux可以启动,就是在windows启动不了。问题提示:现象一:2023-10-2713:40:05.682ERROR11736---[main]o.......
  • 关于javascript的一些笔记(一)
    在script标签内使用import的时候,必须在script标签加上type=“module”当使用script标签加上type="module"的时候,是当所有模块都加载进来才进行工作的,也就是如果html在script标签下面也是可以正常运行的,他是后解析的当使用script标签加上type="module"的时候,script标签里面......
  • 每日一道Java面试题:Java是值传递还是引用传递?
    写在开头Java是值传递还是引用传递?这个问题几乎100%的出现在了各大主流Java面试题中,知识点很小,但很考验面试者对于Java运行的理解,今晚趁着生产投产的空子,过来小聊一下。实参与形参所谓的值传递or引用传递是指方法在调用的过程中实参传递的两种变现形式,那么好,想搞清楚这个问题的......
  • Java商城单体和微服务架构有什么区别
    微服务架构概述BizSpring移动全端国际化电商平台,是建立在SpringCloud基础上的微服务应用,服务化是系统达到一定规模以后的必然选择,主流的互联网公司基本都在迁移到服务化架构。我们的微服务化架构给客户带来更多便捷,每个开发团队及各人更加专注于自身业务的开发,每个服务独立......
  • Java学习日记 Day12 心累~
    SpringMVC:主要学了SpringMVC架构下请求与响应的各种方式,在响应中要知道请求转发和重定向的区别。算法:合并二叉树:判断当前节点两棵树的数值关系,然后递归判断左右子树的关系。二叉搜索树中的搜索:根据二叉搜索树的特点,递归查找左右子树,当值相等就返回。验证二叉搜索树:为自己的左......
  • 2024年1月Java项目开发指南15:vue3+AntDesignVue 设计页面
    考虑到有的同学对vue3不熟悉,因此,我把ControlView.vue这个页面清空,我们从0开始写。<templatestyle="width:100%"></template><scriptsetup></script><stylescoped></style>搭建页面的基本框架展开代码后复制你需要的代码。比如我选择上中下这种结构,我就复制上......
  • java IO
    I/O流什么事文件文件就是保存数据的地方文件流文件在程序中是以流的方式来操作的流:数据在数据源(文件)和程序(内存之间)经历的路径输入流:数据从数据源(文件)到程序(内存)的路径输出流:数据从程序(内存)到数据源文件的路径1.常用创建文件的操作创建文件对象相关的......
  • 1.JAVA基础-JDK的介绍
    Java语言语言:人与人交流沟通的表达方式。计算机语言:人与计算机之间进行信息交流沟通的一种特殊语言。Java语言是美国Sun公司(StanfordUniversityNetwork)在1995年推出的计算机语言。Java之父:詹姆斯·高斯林(JamesGosling)。Java语言的三个版本⚫JavaSE⚫JavaME......