java枚举类是怎么初始化的,为什么说枚举类是线程安全的
今天写枚举类的时候发现了一个有趣的现象,在这里分享一下:
首先我们定义一个简单的枚举类:
/*** @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枚举类是怎么初始化的,为什么说枚举类是线程安全的相关推荐
- 【转载】c#类的成员初始化顺序
作者:彭白洋 创建于:2009-01-15 出处:http://www.cnblogs.com/siceblue/archive/2009/01/15/1376430.html 收录于:2013-0 ...
- Java枚举类与注解——一篇文章读懂枚举类与注解
文章目录 一.枚举类 ① 自定义枚举类 ② enum关键字定义枚举类 ③ enum 枚举类的方法 ④ enum 枚举类实现接口 二.注解 ① 生成文档相关注解 ②注解在编译时进行格式检查 ③注解跟踪代 ...
- 【Kotlin】Kotlin enum 枚举类 ( 常用用法 | 初始化成员变量 | 实现抽象方法 | 实现接口 | 获取名称和位置索引 | 调用枚举常量方法 )
文章目录 I . 枚举类常用用法 II . 枚举类初始化 III. 枚举类匿名类 IV . 枚举类实现接口 V . 获取枚举常量名称和位置索引 VI . 获取枚举常量的成员变量 VII . 调用枚举常 ...
- 28 Java类的加载机制、什么是类的加载、类的生命周期、加载:查找并加载类的二进制数据、连接、初始化、类加载器、双亲委派模型、自定义类加载器
28Java类的加载机制 28.1.什么是类的加载 28.2.类的生命周期 28.2.1.加载:查找并加载类的二进制数据 28.2.2.连接 28.2.3.初始化 28.3.类加载器 28.4.类的加 ...
- Java类和对象初始化
首先对Java 较为深层技术提几个问题(包含class 文件格式的了解): 1.类的访问权限在class二进制文件中怎么体现的? 2.类中static 区域 怎么初始化的,时间,顺序,特点是什么? 3 ...
- java 类 加载 初始化_java中类的初始化和加载
最近在阅读孙卫琴的java面向对象一书中,看到对java中类的初始化和加载中的论述比较系统,故笔记之 1)类的初始化,JAVA在初始化一个类时,以下步骤 A 假如类存在直接的父类,并且这个父类还没有初 ...
- java枚举返回字符串_枚举工具类-通过给定值获取对应的枚举类
开发背景: 在开发过程中遇到需要通过给定的值来获取对应的枚举值,如下例枚举类中,需要通过传入"春"来获取SPRING. public 开始尝试通过Enum的内置方法valueOf( ...
- Java必突-JVM知识专题(一): Java代码是如何跑起来的+类加载到使用的过程+类从加载到使用核心阶段(类初始化)+类加载的层级结构+什么是JVM的内存区域划分?Java虚拟机栈、Java堆内存
前言: 该章节知识点梳理:本文主要是入门和了解jvm,不做深入 1.Java代码是如何运行起来的? 2.类加载到使用的过程? 3.验证准备和初始化的过程? 4.类从加载到使用核心阶段:初始化.类加载器 ...
- java.lang.NoClassDefFoundError:无法初始化类XXX
大约阅读2分钟,写于 2021 0408 22:31 北京石景山家里台灯下 java.lang.NoClassDefFoundError:无法初始化类XXX 文章目录 1. 场景 2. 问题 3. 原 ...
最新文章
- 含有计算机专业词的告别文案,那些超级适合告别的文案,充满了对过往的怀念和遗憾...
- python二维表转一维表_Excel、Power BI及Python系列:使用Power BI转化一维表与二维表...
- 单机redis 主从实例
- 为什么“不在乎别人的眼光”是个大谎言?
- 组信箱共享及挂载介绍
- 小辣椒p60手机怎么样_奇葩对决!3600元的格力手机与3599元的小辣椒V19,谁更强?...
- Asp.Net Core 使用Quartz基于界面画接口管理做定时任务
- L1-034 点赞 (20 分)
- html表单文本框作用,HTML表单的用法
- C语言博客作业08,C语言I博客作业08
- 加速新冠疫苗研发,阿里云免费开放一切AI算力!
- SQL2005下载版本之区别
- 怎样在神经网络设计中加入先验信息 - 权值共享
- 营收与预测:线性回归建立预测收入水平的线性回归模型。
- Oracle卸载方法
- ST芯片烧录失败的原因分析及对策
- 服务器能ping通,但是无法ssh
- java 事务管理 子父线程_java父线程子线程(转)
- 不吹不黑!逛 GitHub 没看过这 10 个开源项目,绝对血亏...
- 产品经理如何推动项目落地