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 技術分享
并發編程網
搜索
積分與排名
積分 - 598894
排名 - 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配置(134347)
2.?Unknown Source的出現及解決(39487)
3.?MMORPG服務器架構(33463)
4.?Java8之Stream/Map(24532)
5.?淺談Eclipse dropins插件安裝的"坑"(附m2e的各個版本插件下載)(19626)
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片苍井空
|
18禁美女裸体免费网站
|
国产aⅴ无码专区亚洲av
|
特级做A爰片毛片免费看无码
|
亚洲综合区小说区激情区
|
一级免费黄色大片
|
亚洲国产精品尤物yw在线
|
a在线视频免费观看在线视频三区
|
亚洲 另类 无码 在线
|
五月婷婷免费视频
|
亚洲一区二区三区香蕉
|
香蕉免费一区二区三区
|
亚洲高清免费在线观看
|
成人免费无码视频在线网站
|
亚洲日本VA午夜在线影院
|
国产色爽女小说免费看
|
一个人晚上在线观看的免费视频
|
国产亚洲大尺度无码无码专线
|
在线看片免费人成视频福利
|
99久久精品国产亚洲
|
国产精品成人免费一区二区
|
国产午夜精品理论片免费观看
|
亚洲精品国产精品乱码不99
|
午夜无码A级毛片免费视频
|
中文字幕亚洲男人的天堂网络
|
永久黄网站色视频免费观看
|
九九久久精品国产免费看小说
|
久久亚洲精品成人
|
免费国产黄线在线观看
|
jizz18免费视频
|
亚洲男人天堂av
|
日本不卡视频免费
|
日韩免费高清播放器
|
亚洲无mate20pro麻豆
|
亚洲日本中文字幕一区二区三区
|
污视频在线观看免费
|
亚洲狠狠色丁香婷婷综合
|
国产亚洲综合成人91精品
|
成年女性特黄午夜视频免费看
|