用枚举enum实现单例
生活随笔
收集整理的這篇文章主要介紹了
用枚举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实现单例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 头脑王者有多少个段位?头脑王者怎么升段位
- 下一篇: java序列化与深度拷贝