【java 基础】枚举深思之反编译枚举类,验证枚举实现单例是线程安全的

前言:

用枚举实现单例是线程的,想必大家都知道,但是具体是什么原理大家知道吗,如果不知道请看下本博客,一定会让你明白的

1、枚举实现的单例
public enum Singleton {
    INSTANCE;
    public void doSomething(){
        System.out.println("doSometing");
    }
}
2、反编译此类后的结果
public final class Singleton extends Enum
{

    public static Singleton[] values()
    {
        return (Singleton[])$VALUES.clone();
    }

    public static Singleton valueOf(String name)
    {
        return (Singleton)Enum.valueOf(com/danli/test3/Singleton, name);
    }

    private Singleton(String s, int i)
    {
        super(s, i);
    }

    public void doSomething()
    {
        System.out.println("doSometing");
    }

    public static final Singleton INSTANCE;
    private static final Singleton $VALUES[];

    static 
    {
        INSTANCE = new Singleton("INSTANCE", 0);
        $VALUES = (new Singleton[] {
            INSTANCE
        });
    }
}

从反编译的结果来看,我们只关注以下部分

// 构造器私有化
public final class Singleton extends Enum
{
    private Singleton(String s, int i)
    {
        super(s, i);
    }
    public static final Singleton INSTANCE;
    private static final Singleton $VALUES[];

    static 
    {
        INSTANCE = new Singleton("INSTANCE", 0);
        $VALUES = (new Singleton[] {
            INSTANCE
        });
    }

首先INSTANCE被static final修饰,构造器也是私有化的,这种方式不就是单例模式吗?在实例的时候,其实是在静态代码块中实例化的。 这就保证了线程安全

其次我们看super(s, i);这句代码,Singleton反编译后为继承Enum,所以super(s,i)执行的是Enmu中的构造方法,我们看下Enum的部分源码:

    private final String name;

 
    public final String name() {
        return name;
    }


    private final int ordinal;

 
    public final int ordinal() {
        return ordinal;
    }

    protected Enum(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }

 
    public String toString() {
        return name;
    }

然后我在梳理一下

 INSTANCE = new Singleton("INSTANCE", 0);
    private Singleton(String s, int i)
    {
        super(s, i);
    }

    protected Enum(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }

看上面的三段代码,这也验证了如果执行 System.out.println(Singleton.INSTANCE) 执行的结果是INSTANCE

3、反编译工具的介绍
(1)下载工具jad

链接:https://dl.pconline.com.cn/download/532245.html
下载完后
在这里插入图片描述

2、进入dos然后目录进入到jad.exe所在的位置

此时将要反编译的文件也放到相同位置:
在这里插入图片描述

然后输入命令 jad -s java Singleton.class
在这里插入图片描述
此时生成一个反编译好的文件:Singleton.java

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值