今天写枚举类的时候发现了一个有趣的现象,在这里分享一下:

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

/*** @author jinghuaixin* @date 2020/04/30*/
public enum Week {Monday, Tuesday;// 静态代码块static {System.out.println("枚举中静态代码块执行了");}// 构造方法private Week() {System.out.println("枚举中构造方法执行了");}// 构造代码块{System.out.println("枚举中代码块执行了");}
}

然后定义一个简单的测试类:

public class TestEnum {static {System.out.println("普通类中静态代码块执行了");}{System.out.println("普通类中代码块执行了");}public TestEnum() {System.out.println("普通类的构造方法执行了");}public static void main(String[] args) {new TestEnum();System.out.println("+++++++++++++++++++++++++++");new TestEnum();System.out.println("=========================");Week week = Week.Monday;System.out.println("=========================");Week week2 = Week.Tuesday;}}

运行结果:

普通类中静态代码块执行了
普通类中代码块执行了
普通类的构造方法执行了
+++++++++++++++++++++++++++
普通类中代码块执行了
普通类的构造方法执行了
=========================
枚举中代码块执行了
枚举中构造方法执行了
枚举中代码块执行了
枚举中构造方法执行了
枚举中静态代码块执行了
=========================

普通类中,静态代码块在类加载的时候执行,类只会加载一次,所以只会执行一次,并且这个动作在对象实例化之前,所以是最先输出的,紧接着每次实例化都会去调用构造代码块和构造方法,所以会2次输出。但是枚举类就比较有趣了,可以看到枚举类中第一次使用的时候,调用构造代码块和构造方法块执行次数和枚举元素相等,第二次并没有再调用构造代码块和构造方法,静态代码块虽然也只执行了一次,但是却放在最后了,这是为什么呢?

我们借助jad反编译一下枚举类的代码:

jad Week.class

反编译生成的代码:

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name:   Week.javapackage learnbymaven.single;import java.io.PrintStream;public final class Week extends Enum
{private Week(String s, int i){super(s, i);System.out.println("枚举中代码块执行了");System.out.println("枚举中构造方法执行了");}public static Week[] values(){Week aweek[];int i;Week aweek1[];System.arraycopy(aweek = ENUM$VALUES, 0, aweek1 = new Week[i = aweek.length], 0, i);return aweek1;}public static Week valueOf(String s){return (Week)Enum.valueOf(learnbymaven/single/Week, s);}public static final Week Monday;public static final Week Tuesday;private static final Week ENUM$VALUES[];// 静态代码块初始化变量static {Monday = new Week("Monday", 0);Tuesday = new Week("Tuesday", 1);ENUM$VALUES = (new Week[] {Monday, Tuesday});System.out.println("枚举中静态代码块执行了");}
}

通过反编译代码可以看到,枚举底层其实还是class,枚举元素是被声明成public static final的成员变量(可以通过类名直接调用),并且在static静态代码块中一起初始化了,这就解释了为什么第一次调用枚举类的时候,构造代码块和构造方法执行次数会和枚举元素相等,因为第一次加载类的时候就全部初始化了。由于java类的加载和初始化过程都是线程安全的,所以创建一个enum类型是线程安全的

java枚举类是怎么初始化的,为什么说枚举类是线程安全的相关推荐

  1. 【转载】c#类的成员初始化顺序

    作者:彭白洋 创建于:2009-01-15 出处:http://www.cnblogs.com/siceblue/archive/2009/01/15/1376430.html  收录于:2013-0 ...

  2. Java枚举类与注解——一篇文章读懂枚举类与注解

    文章目录 一.枚举类 ① 自定义枚举类 ② enum关键字定义枚举类 ③ enum 枚举类的方法 ④ enum 枚举类实现接口 二.注解 ① 生成文档相关注解 ②注解在编译时进行格式检查 ③注解跟踪代 ...

  3. 【Kotlin】Kotlin enum 枚举类 ( 常用用法 | 初始化成员变量 | 实现抽象方法 | 实现接口 | 获取名称和位置索引 | 调用枚举常量方法 )

    文章目录 I . 枚举类常用用法 II . 枚举类初始化 III. 枚举类匿名类 IV . 枚举类实现接口 V . 获取枚举常量名称和位置索引 VI . 获取枚举常量的成员变量 VII . 调用枚举常 ...

  4. 28 Java类的加载机制、什么是类的加载、类的生命周期、加载:查找并加载类的二进制数据、连接、初始化、类加载器、双亲委派模型、自定义类加载器

    28Java类的加载机制 28.1.什么是类的加载 28.2.类的生命周期 28.2.1.加载:查找并加载类的二进制数据 28.2.2.连接 28.2.3.初始化 28.3.类加载器 28.4.类的加 ...

  5. Java类和对象初始化

    首先对Java 较为深层技术提几个问题(包含class 文件格式的了解): 1.类的访问权限在class二进制文件中怎么体现的? 2.类中static 区域 怎么初始化的,时间,顺序,特点是什么? 3 ...

  6. java 类 加载 初始化_java中类的初始化和加载

    最近在阅读孙卫琴的java面向对象一书中,看到对java中类的初始化和加载中的论述比较系统,故笔记之 1)类的初始化,JAVA在初始化一个类时,以下步骤 A 假如类存在直接的父类,并且这个父类还没有初 ...

  7. java枚举返回字符串_枚举工具类-通过给定值获取对应的枚举类

    开发背景: 在开发过程中遇到需要通过给定的值来获取对应的枚举值,如下例枚举类中,需要通过传入"春"来获取SPRING. public 开始尝试通过Enum的内置方法valueOf( ...

  8. Java必突-JVM知识专题(一): Java代码是如何跑起来的+类加载到使用的过程+类从加载到使用核心阶段(类初始化)+类加载的层级结构+什么是JVM的内存区域划分?Java虚拟机栈、Java堆内存

    前言: 该章节知识点梳理:本文主要是入门和了解jvm,不做深入 1.Java代码是如何运行起来的? 2.类加载到使用的过程? 3.验证准备和初始化的过程? 4.类从加载到使用核心阶段:初始化.类加载器 ...

  9. java.lang.NoClassDefFoundError:无法初始化类XXX

    大约阅读2分钟,写于 2021 0408 22:31 北京石景山家里台灯下 java.lang.NoClassDefFoundError:无法初始化类XXX 文章目录 1. 场景 2. 问题 3. 原 ...

最新文章

  1. 含有计算机专业词的告别文案,那些超级适合告别的文案,充满了对过往的怀念和遗憾...
  2. python二维表转一维表_Excel、Power BI及Python系列:使用Power BI转化一维表与二维表...
  3. 单机redis 主从实例
  4. 为什么“不在乎别人的眼光”是个大谎言?
  5. 组信箱共享及挂载介绍
  6. 小辣椒p60手机怎么样_奇葩对决!3600元的格力手机与3599元的小辣椒V19,谁更强?...
  7. Asp.Net Core 使用Quartz基于界面画接口管理做定时任务
  8. L1-034 点赞 (20 分)
  9. html表单文本框作用,HTML表单的用法
  10. C语言博客作业08,C语言I博客作业08
  11. 加速新冠疫苗研发,阿里云免费开放一切AI算力!
  12. SQL2005下载版本之区别
  13. 怎样在神经网络设计中加入先验信息 - 权值共享
  14. 营收与预测:线性回归建立预测收入水平的线性回归模型。
  15. Oracle卸载方法
  16. ST芯片烧录失败的原因分析及对策
  17. 服务器能ping通,但是无法ssh
  18. java 事务管理 子父线程_java父线程子线程(转)
  19. 不吹不黑!逛 GitHub 没看过这 10 个开源项目,绝对血亏...
  20. 产品经理如何推动项目落地

热门文章

  1. ios 应用特殊节日页面整体变灰
  2. 论文解读:PF磷酸:基于机器学习的磷酸化位点预测疟原虫蛋白的工具
  3. POJ 1006 生理周期
  4. 说一点学习python的心得
  5. python爬猫眼电影影评,EX1 | 用Python爬取猫眼电影 APP 关于《无双》电影评论
  6. 三次函数求近似解(牛顿迭代法/二分法)
  7. 经典文献阅读之--Cam2BEV
  8. sql string转为日期_SQL之变身Excel(二)
  9. 【区块链 | Compound】2.剖析DeFi借贷产品之Compound:合约篇
  10. Java—文件传输助手单机版,你值得拥有