前幾天看了下公司代碼中的一個單例類,發現居然是用靜態內部類實現的。后面在網上找了下資料,發現使用靜態內部實現的單例是懶加載的且線程安全。
從網上資料得出如下結論:
加載一個類時,其內部類不會同時被加載。一個類被加載,當且僅當其某個靜態成員(靜態域、構造器、靜態方法等)被調用時發生。
一、代碼
package com.zxy.test;
/**
* 使用靜態內部類實現的單例類
* @author ZENG.XIAO.YAN
* @date 2017-08-08 10:29:20
* @version V1.0
*/
public class UserSingleton {
/** 私有化構造器 */
private UserSingleton() {
}
/** 對外提供公共的訪問方法 */
public static UserSingleton getInstance() {
return UserSingletonHolder.INSTANCE;
}
/** 寫一個靜態內部類,里面實例化外部類 */
private static class UserSingletonHolder {
private static final UserSingleton INSTANCE = new UserSingleton();
}
}
26
1
package com.zxy.test;
2
/**
3
* 使用靜態內部類實現的單例類
4
* @author ZENG.XIAO.YAN
5
* @date 2017-08-08 10:29:20
6
* @version V1.0
7
*/
8
9
public class UserSingleton {
10
11
/** 私有化構造器 */
12
private UserSingleton() {
13
}
14
15
/** 對外提供公共的訪問方法 */
16
public static UserSingleton getInstance() {
17
return UserSingletonHolder.INSTANCE;
18
}
19
20
21
/** 寫一個靜態內部類,里面實例化外部類 */
22
private static class UserSingletonHolder {
23
private static final UserSingleton INSTANCE = new UserSingleton();
24
}
25
26
}
package com.zxy.test;
/**
* 使用靜態內部類實現的單例類
* @author ZENG.XIAO.YAN
* @date 2017-08-08 10:29:20
* @version V1.0
*/
public class UserSingleton {
/** 私有化構造器 */
private UserSingleton() {
}
/** 對外提供公共的訪問方法 */
public static UserSingleton getInstance() {
return UserSingletonHolder.INSTANCE;
}
/** 寫一個靜態內部類,里面實例化外部類 */
private static class UserSingletonHolder {
private static final UserSingleton INSTANCE = new UserSingleton();
}
}
x
1
package com.zxy.test;
2
/**
3
* 使用靜態內部類實現的單例類
4
* @author ZENG.XIAO.YAN
5
* @date 2017-08-08 10:29:20
6
* @version V1.0
7
*/
8
public class UserSingleton {
9
10
/** 私有化構造器 */
11
private UserSingleton() {
12
}
13
14
/** 對外提供公共的訪問方法 */
15
public static UserSingleton getInstance() {
16
return UserSingletonHolder.INSTANCE;
17
}
18
19
/** 寫一個靜態內部類,里面實例化外部類 */
20
private static class UserSingletonHolder {
21
private static final UserSingleton INSTANCE = new UserSingleton();
22
}
23
24
}
二、小結
(1)為什么這樣實現就是單例的?
因為這個類的實例化是靠靜態內部類的靜態常量實例化的。
INSTANCE 是常量,因此只能賦值一次;它還是靜態的,因此隨着內部類一起加載。
(2)這樣實現有什么好處?
我記得以前接觸的懶漢式的代碼好像有線程安全問題,需要加同步鎖才能解決。
采用靜態內部類實現的代碼也是懶加載的,只有第一次使用這個單例的實例的時候才加載;
同時不會有線程安全問題
(3)參考文檔