【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
下载完后
2、进入dos然后目录进入到jad.exe所在的位置
此时将要反编译的文件也放到相同位置:
然后输入命令 jad -s java Singleton.class
此时生成一个反编译好的文件:Singleton.java
本文地址:https://blog.csdn.net/jerry11112/article/details/112603044
上一篇: Java基础语法_包装类和日期类