爱上JDK源码阅读-枚举类

在日常开发中,经常会用到枚举类。这篇文章主要探讨一下枚举类和普通类有什么区别,以及编译过程中偷偷做了什么事情。

知识点

  • 枚举类的本质
  • 编译器对枚举类的改动

先看一段简单的枚举类代码:

 enum StatusType {ON(1) ,OFF(2);StatusType(int code) {this.code = code;}private final int code;}

使用Compiler Explorer工具,编译成字节码

在这里插入图片描述

从上面的截图中可以看到,枚举类本质上也是一个普通类,同时继承了Enum类,而且还是final的。所以说类可以做到的事情,枚举类也可以,比如定义成员变量和成员方法。

除了自动继承了Enum类,还声明了一些静态变量和静态方法。
在这里插入图片描述

我们在枚举类定义的ONOFF对象,本质是一个静态变量。

public static final StatusType ON;public static final StatusType OFF;

在开发中经常用到的values()和valueOf()方法,也是编译器自动帮忙生成的

private static final StatusType[] $VALUES;public static StatusType[] values();0: getstatic     #10                 // Field $VALUES:[LStatusType;3: invokevirtual #14                 // Method "[LStatusType;".clone:()Ljava/lang/Object;6: checkcast     #15                 // class "[LStatusType;"9: areturnpublic static StatusType valueOf(java.lang.String);0: ldc           #4                  // class StatusType2: aload_03: invokestatic  #5                  // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;6: checkcast     #4                  // class StatusType9: areturn   

上面只是声明定义了一个静态变量,还未进行初始化,下面static块进行初始化

static {};0: new           #1                  // class StatusType3: dup4: ldc           #33                 // String ON6: iconst_07: iconst_18: invokespecial #34                 // Method "<init>":(Ljava/lang/String;II)V11: putstatic     #3                  // Field ON:LStatusType;14: new           #1                  // class StatusType17: dup18: ldc           #37                 // String OFF20: iconst_121: iconst_222: invokespecial #34                 // Method "<init>":(Ljava/lang/String;II)V25: putstatic     #7                  // Field OFF:LStatusType;28: invokestatic  #38                 // Method $values:()[LStatusType;31: putstatic     #10                 // Field $VALUES:[LStatusType;34: return

上面这段字节码主要就是创建了两个实例对象和一个数组,并且把两个实例对象放到数组里。不过有个点可以注意到,在调用构造函数的时候, 调用的是3个参数的构造函数,这里实际上前面两个参数是父类的构造函数需要的。

8: invokespecial #34                 // Method "<init>":(Ljava/lang/String;II)V
    /*** Sole constructor.  Programmers cannot invoke this constructor.* It is for use by code emitted by the compiler in response to* enum type declarations.** @param name - The name of this enum constant, which is the identifier*               used to declare it.* @param ordinal - The ordinal of this enumeration constant (its position*         in the enum declaration, where the initial constant is assigned*         an ordinal of zero).*/protected Enum(String name, int ordinal) {this.name = name;this.ordinal = ordinal;}
总结

1、枚举类本质上也是普通类,并且是final修饰的,继承了Enum类
2、用户定义的枚举对象转换成了静态变量对象
3、枚举类自动添加了values()和valueOf()方法
4、调用构造函数时,会自动调用父类的构造函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/643345.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手机号码携号转网查询API接口是什么

手机号码携号转网查询API接口又叫运营商携号转网查询API接口&#xff0c;是指通过手机号精准查询该号码转网前及转网后所归属运营商。运营商携号转网查询API接口多用于营销场景&#xff0c;如运营商业务办理、客户信息查询、携号转网、电话营销等&#xff0c;接下来我们聊一聊怎…

什么是Spring Security?具有哪些功能?

本篇将带你快速了解什么是Spring Security&#xff0c;通过入门案例以及相关原理和类的分析让你快速入门。 一、概述 官网&#xff1a;https://spring.io/projects/spring-security Spring Security是一个Java框架&#xff0c;用于保护应用程序的安全性。它提供了一套全面的安全…

好看的混淆矩阵

网上绘制的混淆矩阵都不太满意。。。经过本人多次实验&#xff0c;如下混淆矩阵最为美观&#xff0c;特此记录 import matplotlib matplotlib.use(Agg) from matplotlib import rcParamsimport matplotlib.pyplot as plt import numpy as np# 给定混淆矩阵 cm np.array([[683…

5000字干货:如何通过社区驱动增长?挑战、认知、本质和六个步骤!

本来不少平台建立社区是为了给用户提供归属感,但在商业压力下,不得不开始做增长的运营。但不是说只是简单地“做增长”就可以的,归属感和增长,两者看起来相似,但生产流程却完全不同。这种情况下,我们需要怎么做? 2024年经济压力下,CEO向各社区负责人下达了一个目标:实…

解决“找不到MSVCP120.dll”或“MSVCP120.dll丢失”的错误方法

在计算机使用过程中&#xff0c;遇到诸如“找不到MSVCP120.dll”或“MSVCP120.dll丢失”的错误提示并不罕见。这类问题往往会导致某些应用程序无法正常运行&#xff0c;给用户带来困扰。本文旨在详细阐述MSVCP120.dll文件的重要性、其丢失的可能原因&#xff0c;以及解决方法&a…

力扣HOT100 - 543. 二叉树的直径

解题思路&#xff1a; class Solution {int ans;//记录节点数public int diameterOfBinaryTree(TreeNode root) {ans 1;depth(root);return ans - 1;//节点数减 1 就是路径长度}public int depth(TreeNode root) {if (root null) return 0;int l depth(root.left);int r de…

docker容器内彻底移除iptables服务的实现方法

背景 我创建的容器使用的是centos6的标准镜像&#xff0c;所以内置了iptables服务。容器启动后iptables服务默认就启动了。iptables设置的规则默认是所有流量都无法通行。而对于服务器的管理使用的是宿主机的防火墙。这样就导致在实现用iptables动态给容器添加端口映射时不成功…

STM32单片机C语言模块化编程实战:按键控制LED灯并串口打印详解与示例

一、开发环境 硬件&#xff1a;正点原子探索者 V3 STM32F407 开发板 单片机&#xff1a;STM32F407ZGT6 Keil版本&#xff1a;5.32 STM32CubeMX版本&#xff1a;6.9.2 STM32Cube MCU Packges版本&#xff1a;STM32F4 V1.27.1 虽然这里演示的是STM32F407&#xff0c;但是ST…

ClickHouse用UDF解析XML字符串和XML文件

一.如果是读取xml文件的时候&#xff0c;文件入库需要使用文件读取UDF 创建了1个测试文件 wsdFileRead()&#xff1a; 直接读取文件内容 SELECT wsdFileRead(/home/temp/wsd_test.xml)Query id: 09b6e5fe-7169-43f7-b001-90e2eeabb8da┌─wsdFileRead(/home/temp/wsd_test.xm…

关于c++中的操作符:new和delete

目录 1.什么是new和delete 2.new和delete的用法 2.1 new和delete普通用法 2.2 new和delete的升级用法 1.什么是new和delete C语言中有两个函数用于动态开辟、释放内存----malloc和freec中又引入了两个操作符----new和delete来用于开辟、释放内存 说到这应该对这两个操作符有…

西电超算使用方法-简易版

一、引言 西电超算不错&#xff0c;我很喜欢。本文仅供自己学习使用。 二、环境搭建 搭建环境需要有一些依赖库&#xff0c;但是其实西电超算说明手册并没有写的非常清楚。因此&#xff0c;这次实战演示一下&#xff0c;写一个运行sh文件脚本并提交作业。 1、选择GPU还是CP…

JAVA:Kettle 强大的开源ETL工具

请关注微信公众号&#xff1a;拾荒的小海螺 1、简述 Kettle&#xff08;Pentaho Data Integration&#xff09;&#xff1a;强大的开源ETL工具Kettle&#xff0c;又称作Pentaho Data Integration&#xff0c;是一款流行的开源ETL&#xff08;Extract, Transform, Load&#x…