枚舉單例的實現
單例是什麼我在這裏不再詳細說了,其他的餓漢模式單例、懶漢模式單例、雙重加鎖這麼的在此都不討論。我參考了網上其他人寫的枚舉單例,都差不多,沒什麼實用的參考價值,這裏只給出我自己實現的枚舉的單例寫法,並且能夠防止反射,希望大家一起討論。
枚舉單例
package com.example.demo.enums;
import com.example.demo.service.SingletonService;
/**
* @classname: Singleton
* @description: 單例示例
* @author chenhx
* @date 2020-03-18 10:05:17
*/
public enum SingletonOfEnum implements SingletonService {
INSTANCE{
@Override
public String doSomething() {
return "aaa";
}
@Override
public void doPrint(String str) {
System.out.println("this is a function doPrint:" + str);
}
};
public static SingletonOfEnum getInstance(){
return INSTANCE;
}
}
其中枚舉實現了接口SingletonService,這個接口裏可以定義一些我們需要做的一些事,例如
SingletonService.java
/**
* @classname: SingletonService
* @description: 單例接口
* @author chenhx
* @date 2020-03-18 14:18:54
*/
public interface SingletonService {
String doSomething();
void doPrint(String str);
}
測試
@Test
public void test3() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//通過枚舉獲取單例
SingletonOfEnum instance = SingletonOfEnum.getInstance();
String s = instance.doSomething();
System.out.println(s);
instance.doPrint(s);
System.out.println(instance.hashCode());
//通過枚舉獲取單例
SingletonOfEnum instance2 = SingletonOfEnum.getInstance();
System.out.println(instance2.hashCode());
// 通過反射獲取單例
Constructor<SingletonOfEnum> constructor = SingletonOfEnum.class.getDeclaredConstructor();
constructor.setAccessible(true);
SingletonOfEnum singleton3 = constructor.newInstance();
System.out.println(singleton3);
}
通過觀察控制檯,我們發現,通過枚舉獲取的單例對象確實是同一個,但是通過反射獲取實例,就會出現異常,因爲枚舉是不能通過反射去調用他的私有構造方法的。