欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-26 21:57:47
1、...

前言:

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

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
下载完后
【java 基础】枚举深思之反编译枚举类,验证枚举实现单例是线程安全的

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

此时将要反编译的文件也放到相同位置:
【java 基础】枚举深思之反编译枚举类,验证枚举实现单例是线程安全的

然后输入命令 jad -s java Singleton.class
【java 基础】枚举深思之反编译枚举类,验证枚举实现单例是线程安全的
此时生成一个反编译好的文件:Singleton.java

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

本文地址:https://blog.csdn.net/jerry11112/article/details/112603044

相关标签: java