千家信息网

java中jad枚举实现的单例类是怎样的

发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,今天就跟大家聊聊有关java中jad枚举实现的单例类是怎样的,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。首先看下枚举实现的单例类普通的类pu
千家信息网最后更新 2025年01月31日java中jad枚举实现的单例类是怎样的

今天就跟大家聊聊有关java中jad枚举实现的单例类是怎样的,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

  • 首先看下枚举实现的单例类

  1. 普通的类

public class Controller {    public Controller() { }    public void func(){        System.out.println("1");    }}
  1. 我想把它变成单例的(用一个枚举类持有想要实现单例的普通类)

public enum ControllerHolder {    INSTANCE;    private Controller controller;    ControllerHolder() {        this.controller = new Controller();    }    public static Controller getInstance(){        return ControllerHolder.INSTANCE.controller;    }}
  1. 测试下

public static void main(String[] args) {        System.out.println(ControllerHolder.getInstance());        System.out.println(ControllerHolder.getInstance());        System.out.println(ControllerHolder.getInstance());        System.out.println(ControllerHolder.getInstance());        System.out.println(ControllerHolder.getInstance());    }输出:com.iluwatar.singleton.Controller@6e8cf4c6com.iluwatar.singleton.Controller@6e8cf4c6com.iluwatar.singleton.Controller@6e8cf4c6com.iluwatar.singleton.Controller@6e8cf4c6com.iluwatar.singleton.Controller@6e8cf4c6
  • 现在看起来是单例的,但是对多线程支持么?反编译看下

  1. 在源代码目录下,执行 javac ./*.java 将包下的文件全部编译

  2. 用java 自带的javap反编译看看 javap .\ControllerHolder.class

  3. javap 反编译的不太好,看不出具体情况, 还是使用jad 来反编译看看吧

  4. 执行 .\jad.exe D:\workspace_idea_try\java-design-patterns\singleton\src\main\java\com\zzk\singleton\ControllerHolder.class 会在jad.exe同级目录生成一个ControllerHolder.jad文件.内容如下↓↓↓

  • 最后反编译的文件

public final class ControllerHolder extends Enum{    public static ControllerHolder[] values()    {        return (ControllerHolder[])$VALUES.clone();    }    public static ControllerHolder valueOf(String s)    {        return (ControllerHolder)Enum.valueOf(com/zzk/singleton/ControllerHolder, s);    }    private ControllerHolder(String s, int i)    {        super(s, i);        controller = new Controller();    }    public static Controller getInstance()    {        return INSTANCE.controller;    }    public static final ControllerHolder INSTANCE;    //controller会随ControllerHolder的初始化而初始化    private Controller controller;    private static final ControllerHolder $VALUES[];    static     {        INSTANCE = new ControllerHolder("INSTANCE", 0);        $VALUES = (new ControllerHolder[] {            INSTANCE        });    }}
  1. public final class ControllerHolder extends Enum 这一行说明 枚举就是一个普通的类,只是继承了Enum类.

  2. public static final ControllerHolder INSTANCE; 这一行, ControllerHolder是静态的,并且INSTANCE = new ControllerHolder("INSTANCE", 0);在静态代码块中执行, 这种方式 jvm会保证运行static代码块是线程安全并且只执行一次的,所以Controller作为ControllerHolder的一个属性,自然也只声明一次和线程安全的

  3. 这种枚举单例的实现并没有延迟加载的优点, 一上来不管用没用到,都在静态方法中初始化了.

  • 上面写的,将Controller和ControllerHolder分开写了,这种方式一般不采用,因为如果有人直接new了一个Controller,会导致该Controller不是单例了,因此通常的写法是将枚举写成内部枚举类,代码如下↓↓↓

public class SingletonExample7 {    // 私有构造函数    private SingletonExample7() {}    public static SingletonExample7 getInstance() {        return Singleton.INSTANCE.getInstance();    }    private enum Singleton {        INSTANCE;        private SingletonExample7 singleton;        // JVM保证这个方法绝对只调用一次        Singleton() {            singleton = new SingletonExample7();        }        public SingletonExample7 getInstance() {            return singleton;        }    }}

看完上述内容,你们对java中jad枚举实现的单例类是怎样的有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。

0