I want to fly higher
programming Explorer
BlogJava
首頁
新隨筆
新文章
聯系
聚合
管理
posts - 114,comments - 263,trackbacks - 0
<
2013年3月
>
日
一
二
三
四
五
六
24
25
26
27
28
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
1
2
3
4
5
6
常用鏈接
我的隨筆
我的文章
我的評論
我的參與
最新評論
留言簿
(5)
給我留言
查看公開留言
查看私人留言
隨筆分類
(161)
Book(25)
ClassLoader(5)
Concurrency
Dababase
GameServer(10)
HighPerformance
HotSwap(9)
IO
JVM(6)
Language(2)
Mobile
NetWork(2)
NoSQL
Note(8)
OS(6)
Program(69)
Script(1)
ServerFramework(6)
Shell
Sources(8)
Translations
Utils(4)
隨筆檔案
(114)
2018年6月 (1)
2018年3月 (1)
2017年3月 (2)
2017年2月 (2)
2017年1月 (1)
2016年11月 (2)
2016年7月 (4)
2016年6月 (3)
2016年5月 (2)
2015年12月 (2)
2015年10月 (1)
2015年8月 (1)
2015年7月 (4)
2015年6月 (5)
2014年12月 (1)
2014年11月 (4)
2014年4月 (1)
2014年3月 (3)
2014年2月 (5)
2014年1月 (1)
2013年12月 (7)
2013年11月 (4)
2013年8月 (5)
2013年7月 (3)
2013年3月 (6)
2013年1月 (6)
2012年7月 (1)
2011年12月 (9)
2011年8月 (2)
2011年5月 (1)
2011年2月 (2)
2011年1月 (1)
2010年12月 (2)
2010年11月 (1)
2010年7月 (8)
2010年4月 (3)
2010年3月 (3)
2010年2月 (2)
2010年1月 (2)
文章分類
(2)
學習筆記(2)
文章檔案
(2)
2011年12月 (2)
Alibaba
搜索技術博客-淘寶
淘寶開源項目
阿里中間件團隊博客
阿里技術嘉年華
阿里核心系統團隊博客
Comprehensive
InfoQ - 促進軟件開發領域知識與創新的傳播
LinkedIn
stackoverflow
伯樂在線
內存-溢出 為程序員服務
騰訊大講堂
解道
Expert
jrebel
國外牛博
并發編程高手
莊周夢蝶
洞庭散人
美團技術博客
褚霸
Game
云風
Java
JavaEye做最棒的軟件開發交流社區
coderanch
IBM developerWorks 中國 Java 技術專區
Java Tutorials
Javalobby
javapapers
java-source
java-tips
javaworld
Java極客
Java譯站
Programming Tutorial
TheServerSide
專注Java & Android 技術分享
并發編程網
搜索
積分與排名
積分 - 598778
排名 - 78
最新評論
1.?re: Eclipse反編譯工具Jad及插件JadClipse配置
剛剛問題解決了,file types中, .class下還有一個 .class without source。
把這個也設置成JadClipse為默認選項打開嘛,即可。
謝謝版主~~~
--tangyuan
2.?re: Eclipse反編譯工具Jad及插件JadClipse配置
eclipse4.6版本,按照上述來的不行,版主還有推薦的反編工具嘛,推薦一個呢
--tangyuan
3.?re: 交換兩個值,不用臨時變量(C位運算)[未登錄]
評論內容較長,點擊標題查看
--123
4.?re: Markdown基礎語法及發布blog
確實很基礎的語法,很容易就學會了!
--有機綠茶
5.?re: Java8之Stream/Map[未登錄]
總結的很詳細!
--jay
閱讀排行榜
1.?Eclipse反編譯工具Jad及插件JadClipse配置(134345)
2.?Unknown Source的出現及解決(39483)
3.?MMORPG服務器架構(33461)
4.?Java8之Stream/Map(24530)
5.?淺談Eclipse dropins插件安裝的"坑"(附m2e的各個版本插件下載)(19624)
Effective Java 2nd筆記3:用私有構造器或者枚舉類型強化Singleton屬性
第三條:用私有構造器或者枚舉類型強化Singleton屬性
1.
Singleton指僅僅被實例化一次的類
。Singleton通常被用來代表那些本質上唯一的系統組件,如窗口管理器或者文件系統。使類稱為Singleton會使它的客戶端調試變的十分困難,因為無法給Singleton替換模擬實現,除非它實現一個充當其類型的接口.
2.在
Java1.5發行版本之前,實現Singleton有兩種方法
。這兩種方法都要把構造器保持為私有,并導出公有的靜態成員,以便客戶端能夠訪問該類的唯一實例,以便允許client能夠訪問該類的唯一實例。
3.第一種方法中,公有靜態成員是個final域:
public class Singleton1
{
public static final Singleton1 INSTANCE = new Singleton1();
//私有改造函數
private Singleton1()
{
}
//其他方法實現
public void otherMethod()
{
//...
}
}
私有構造器僅被調用一次,用來實例化公有的靜態final域Singleton1.INSTANCE.由于缺少公有的或者受保護的構造器,所以保證了Singleton1的全局唯一性。一旦其被實例化,只會存在一個實例,不多也不少。客戶端的任何行為都不會改變這一點。
注
:享有特權的client可以借助AccessibleObject.setAccessible方法,通過反射機制調用私有構造器。如果要抵御這種攻擊,需要修改構造器,讓其在創建第二個實例的時候拋出異常。
4.在實現Singleton的第二種方法中,公有的成員是個靜態工廠方法:
public class Singleton2
{
//私有static Instance
private static final Singleton2 INSTANCE = new Singleton2();
//私有構造函數
private Singleton2()
{
}
//獲取單例方法
public static Singleton2 getInstance()
{
return INSTANCE;
}
//其他方法
public void otherMethod()
{
//...
}
}
對于靜態方法Singleton2.getInstance的所有調用,都會返回同一個對象引用,所以永遠不會創建其他的實例。
注
:上述利用反射的提醒依然適用。
5.公有域方法的好處在于,組成類的成員的聲明很清楚的表明了這個類是一個Singleton(final),公有的靜態域是final的,所以該域將總是包含相同的對象引用。公有域方法在性能上不再有任何優勢:現在JVM實現幾乎都能都將靜態工廠方法的調用內聯化。
注:內聯
:指函數在被調用的地方直接展開,編譯器在調用時不用像一般函數那樣,參數壓棧,返回時參數出棧以及資源釋放等,這樣提高了程序執行速度.
6.工廠方法的
優勢
在于,它提供了靈活性:在不改變其API的前提下,我們可以改變該類是否為Singleton的想法。工廠方法返回該類的唯一實例,不過它可以很容易被修改,如改成為每個調用該方法的線程返回一個唯一的實例。
第二個優勢在于與
泛型
有關。
這些優勢之間通常不相關,public域的方法比較簡單.
7.以上的兩種的其中一種方法實現的Singleton類如果變成是可
序列化
的Serialiazble,僅僅在聲明加上implements Serializable是不夠的。為了維護并保證Singleton,必須聲明所有實例都是瞬時transient的,并提供 一個readResolve方法。否則每次反序列化一個序列化的實例時,都會創建一個新的實例。即會導致一個假冒的對象。為了防止這種情況,需要在單例類中增加readResolve方法->
注:readResolve
方法用來重新指定反序列化得到的對象.
private Object readResolve()
{
return INSTANCE;
}
8.
從Java 1.5發行版本起,實現Singleton還有第三種方法。只需編寫一個包含單個元素的枚舉類型。
public Enum Singleton3
{
INSTANCE;
public void otherMethod()
{
}
}
這種方法在功能上與公有域方法相近,但是其更加簡潔,無償提供了序列化機制,絕對防止多次實例化,即使是面對復雜的序列化或者反射攻擊的時候。 雖然這種方法還沒有廣泛使用,但是單元素的枚舉類型已經成為實現Singleton的最佳方法。
注:用反射調用私有構造函數:報錯:
Exception in thread "main" java.lang.IllegalArgumentException: Cannot reflectively create enum objects.
ps:枚舉真心不錯.
部分源碼:
package
com.book.chap2.singleton;
import
java.lang.reflect.Constructor;
/** */
/**
*
* 單例實現1
* <p>
* 公有靜態成員是個public final域
* <p>
* 為防止client利用反射調用私有改造函數,所以在創建第二個實例的時候拋出了異常
*
*
@author
landon
*
@since
1.6.0_35
*
@version
1.0.0 2013-1-9
*
*/
public
class
Singleton1
{
public
static
final
Singleton1 instance
=
new
Singleton1();
//
私有改造函數
private
Singleton1()
{
if
(instance
!=
null
)
{
throw
new
IllegalArgumentException(
"
No exist the second instance
"
);
}
}
//
其他方法實現
public
void
otherMethod()
{
//
System.out.println(
"
call otherMethod
"
);
}
@SuppressWarnings(
"
rawtypes
"
)
public
static
void
main(String
args)
throws
Exception
{
Singleton1 singleton
=
Singleton1.instance;
singleton.otherMethod();
//
利用反射調用私有構造器
Constructor[] arrayConstructor
=
singleton.getClass()
.getDeclaredConstructors();
for
(Constructor constructor : arrayConstructor)
{
//
調用setAccessible(true);
constructor.setAccessible(
true
);
//
實例化,這里一定會拋出異常
constructor.newInstance();
}
}
}
package
com.book.chap2.singleton;
import
java.io.Serializable;
/** */
/**
*
*單例實現2
*<p>公有的成員為靜態工廠方法
*<p>序列化時,要實現readResolve方法,防止反序列化出新的實例
*
*
@author
landon
*
@since
1.6.0_35
*
@version
1.0.0 2013-1-9
*
*/
public
class
Singleton2
implements
Serializable
{
//
私有static Instance
private
static
final
Singleton2 INSTANCE
=
new
Singleton2();
//
私有構造函數
private
Singleton2()
{
}
//
獲取單例方法
public
static
Singleton2 getInstance()
{
return
INSTANCE;
}
//
其他方法
public
void
otherMethod()
{
//
}
//
必須提供該方法,以便重新指定反序列化得到的對象.
private
Object readResolve()
{
return
INSTANCE;
}
}
package
com.book.chap2.singleton;
import
java.lang.reflect.Constructor;
/** */
/**
*
*枚舉實現單例
*<p>目前最好的方式,避免了反射的攻擊和序列化的問題
*
*<pre>
*反射調用枚舉私有構造函數測試結果:
* Exception in thread "main" java.lang.IllegalArgumentException: Cannot reflectively create enum objects
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.book.chap2.singleton.Singleton3.main(Singleton3.java:34)
*</pre>
*
*
@author
landon
*
@since
1.6.0_35
*
@version
1.0.0 2013-1-9
*
*/
public
enum
Singleton3
{
INSTANCE;
public
void
otherMethod()
{
}
public
static
void
main(String
args)
throws
Exception
{
//
測試,是否可以反射生成枚舉
//
利用反射調用私有構造器
Constructor[] arrayConstructor
=
Singleton3.INSTANCE.getClass().ge
tDeclaredConstructors();
for
(Constructor constructor : arrayConstructor)
{
//
調用setAccessible(true);
constructor.setAccessible(
true
);
//
實例化,這里一定會拋出異常
constructor.newInstance();
}
}
}
posted on 2013-03-15 15:38
landon
閱讀(2509)
評論(2)
編輯
收藏
所屬分類:
Program
、
Book
FeedBack:
#
re: Effective Java 2nd筆記3:用私有構造器或者枚舉類型強化Singleton屬性
2013-03-16 10:49 |
背道而馳
注:享有特權的client可以借助AccessibleObject.setAccessible方法,通過反射機制調用私有構造器。如果要抵御這種攻擊,需要修改構造器,讓其在創建第二個實例的時候拋出異常。
請問樓主啊,如果判斷是第二次創建實例?
回復
更多評論
#
re: Effective Java 2nd筆記3:用私有構造器或者枚舉類型強化Singleton屬性
2013-03-16 11:08 |
背道而馳
剛才看了后面曉得了,謝謝樓主的分享!!
回復
更多評論
新用戶注冊
刷新評論列表
只有注冊用戶
登錄
后才能發表評論。
網站導航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
相關文章:
Java游戲服務器基礎技術體系
Disruptor入門Ⅰ-Getting Started
Rust/Go/Node.js/Io.js/Groovy/Scala/Lua 語言入門 Ⅰ
Vertx VS Undertow Ⅰ
Java多線程筆記9-InheritableThreadLocal
Java8之Time/Annotation
Java8之Stream/Map
Java8之Lambda
apache-mina-2.07源碼筆記6-nio細節
Java多線程筆記8-ThreadLocal
Copyright ©2025 landon Powered By
博客園
模板提供:
滬江博客
主站蜘蛛池模板:
亚洲成a人片在线看
|
avtt天堂网手机版亚洲
|
美女被免费网站视频在线
|
67194成是人免费无码
|
久久夜色精品国产噜噜亚洲a
|
1000部夫妻午夜免费
|
亚洲狠狠狠一区二区三区
|
一级女人18毛片免费
|
亚洲乱码在线视频
|
性盈盈影院免费视频观看在线一区
|
亚洲精品国产日韩
|
日本一道本高清免费
|
国产亚洲精品91
|
国产亚洲色视频在线
|
一区二区免费视频
|
亚洲伦理一二三四
|
好吊妞998视频免费观看在线
|
亚洲风情亚Aⅴ在线发布
|
国产午夜免费福利红片
|
国产黄在线播放免费观看
|
亚洲高清国产拍精品26U
|
国产国产人免费视频成69堂
|
亚洲乱码无人区卡1卡2卡3
|
天堂亚洲免费视频
|
全免费a级毛片免费看
|
国产99在线|亚洲
|
mm1313亚洲精品国产
|
久久午夜免费鲁丝片
|
亚洲视频一区二区三区四区
|
免费在线观看亚洲
|
最新久久免费视频
|
亚洲资源最新版在线观看
|
亚洲 小说区 图片区 都市
|
免费一级毛片无毒不卡
|
亚洲狠狠成人综合网
|
国产精品亚洲αv天堂无码
|
91青青国产在线观看免费
|
亚洲av无码乱码国产精品
|
91成人免费观看网站
|
男女交性无遮挡免费视频
|
91天堂素人精品系列全集亚洲
|