日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

用枚举enum实现单例

發布時間:2023/12/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用枚举enum实现单例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【README】

  • 1,effectivejava 講到使用 枚舉類實現單例的例子,非常好用;
  • 2,好處如下:
    • 不用定義私有構造器;
    • 不用定義獲取單例的方法,如 getInstance() ;通過 枚舉類.INSTANCE() 就可以獲取單例了;少了很多代碼;(枚舉類滿足單例天然的性質)

【1】枚舉enum單例

【1.1】枚舉類

/*** @Description kafka管理器* @author xiao tang* @version 1.0.0* @createTime 2021年11月19日*/ public enum PPKafkaManager {/** 單例 */INSTANCE;/** 緩存/kafka集群名-屬性配置映射 */public final ConcurrentMap<String, Properties> kafkaConfigs = new ConcurrentHashMap<>();/*** @description 獲取或添加屬性配置* @param clusterName 集群名* @author xiao tang* @date 2021/11/19 */public Properties getOrCreate(String clusterName) {// 若存在,直接取走if (kafkaConfigs.containsKey(clusterName)) {return kafkaConfigs.get(clusterName);}// 新建kafka屬性Properties newProps = create();Properties oldProps = kafkaConfigs.putIfAbsent(clusterName, newProps);// 若舊屬性存在,則使用舊屬性,丟棄新屬性(注意關閉資源)if (oldProps != null) {// 這里注意關閉資源,其他業務場景可能這里還連接到了kafka集群newProps.clear();}return kafkaConfigs.get(clusterName);}/*** @description 新建kafka屬性* @return kafka屬性* @author xiao tang* @date 2021/11/19*/private Properties create() {// 其他屬性加工邏輯return new Properties();} }

我們發現,基于枚舉實現的單例類,我們不用定義私有構造器,不用聲明getInstance方法,因為 PPKafkaManager.INSTANCE 就可以引用單例


【1.2】枚舉類構造器

【1.2.1】為啥枚舉類可以沒有私有構造器 ?

為此,我們反編譯了? PPKafkaManager 類, 如下:

// 枚舉類反編譯結果 D:\workbench_idea\study4vw\vwstudy01\src>javap com.cmc.vw.javaoop.enumtest.PPKafkaManager Compiled from "PPKafkaManager.java" public final class com.cmc.vw.javaoop.enumtest.PPKafkaManager extends java.lang.Enum<com.cmc.vw.javaoop.enumtest.PPKafkaManager> {public static final com.cmc.vw.javaoop.enumtest.PPKafkaManager INSTANCE;public final java.util.concurrent.ConcurrentMap<java.lang.String, java.util.Properties> kafkaConfigs;public static com.cmc.vw.javaoop.enumtest.PPKafkaManager[] values();public static com.cmc.vw.javaoop.enumtest.PPKafkaManager valueOf(java.lang.String);public java.util.Properties getOrCreate(java.lang.String);static {}; }

我們也可以查看 idea的反編譯結果,發現枚舉類構造器是私有

?

?我們發現

  • 1,PPKafkaManager 枚舉類 編譯后是一個 final 類,所以它是不能被繼承的
  • 2,PPKafkaManager 枚舉類 繼承自 Enum 類
  • 3,枚舉類實例 INSTANCE 是一個static final 靜態常量,僅有一份;所以可以直接引用;
  • 4, 枚舉類 PPKafkaManager 默認為私有構造器;

【1.2.2.】查看 Enum構造器

1)類定義

public abstract class Enum<E extends Enum<E>>implements Comparable<E>, Serializable {

2)Enum 只有一個構造器,如下:

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

很顯然, 這個構造器是 protected,訪問權限是 同包下或其子類,又因為 INSTANCE 被final修飾,所以它不能被繼承,即沒有子類

總結下:

  • 1,Enum枚舉子類的類被final修飾,所以無法被子類繼承;
  • 2,構造器默認為private,所以不能被其他類實例化;
  • 3,通過反射也是無法實例化枚舉類的;
  • 4,線程安全,因為枚舉類實例 被 static final修飾,主程序啟動時,枚舉類實例就已經加載到內存了;

以上,枚舉類天然滿足單例類的條件,且代碼更加簡單

總結

以上是生活随笔為你收集整理的用枚举enum实现单例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。