單例模式的實現有很多種,網上也分析了如今實現單利模式最好用枚舉,好處不外乎三點:
1.線程安全
2.不會因為序列化而產生新實例
3.防止反射攻擊但是貌似沒有一篇文章解釋ENUM單例如何實現了上述三點,請高手解釋一下這三點:
關于第一點線程安全,從反編譯后的類源碼中可以看出也是通過類加載機制保證的,應該是這樣吧(解決)
關于第二點序列化問題,有一篇文章說枚舉類自己實現了readResolve()方法,所以抗序列化,這個方法是當前類自己實現的(解決)
關于第三點反射攻擊,我有自己試著反射攻擊了以下,不過報錯了...看了下方的反編譯類源碼,明白了,因為單例類的修飾是abstract的,所以沒法實例化。(解決)
以下是我寫的一個枚舉單例,以及其class文件反編譯過后的類
枚舉單例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public enum Singleton { INSTANCE { @Override protected void read() { System.out.println( "read" ); } @Override protected void write() { System.out.println( "write" ); } }; protected abstract void read(); protected abstract void write(); } |
反編譯過后還原的類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
public abstract class Singleton extends Enum { private Singleton(String s, int i) { super (s, i); } protected abstract void read(); protected abstract void write(); public static Singleton[] values() { Singleton asingleton[]; int i; Singleton asingleton1[]; System.arraycopy(asingleton = ENUM$VALUES, 0 , asingleton1 = new Singleton[i = asingleton.length], 0 , i); return asingleton1; } public static Singleton valueOf(String s) { return (Singleton)Enum.valueOf(singleton/Singleton, s); } Singleton(String s, int i, Singleton singleton) { this (s, i); } public static final Singleton INSTANCE; private static final Singleton ENUM$VALUES[]; static { INSTANCE = new Singleton( "INSTANCE" , 0 ) { protected void read() { System.out.println( "read" ); } protected void write() { System.out.println( "write" ); } }; ENUM$VALUES = ( new Singleton[] { INSTANCE }); } } |
以上就是JAVA 枚舉單例模式及源碼分析,如有疑問請留言或者到本站社區交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
原文鏈接:http://blog.csdn.net/zmx729618/article/details/66968855