亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Singleton模式序列化問題?

Singleton模式序列化問題?

郎朗坤 2019-04-13 08:45:45
單例實現的一種方式:私有構造器,公有靜態工廠方法publicclassSingleton2{privatestaticfinalSingleton2INSTANCE=newSingleton2();//私有靜態final域/**私有構造器*/privateSingleton2(){}/**公有靜態工廠方法*/publicstaticSingleton2getInstance(){returnINSTANCE;}}為了使利用這種方法實現的Singleton類變成可序列化的,僅僅在申明中加上“implementsSerializable”是不夠的。為了維護并保證Singleton,必須聲明所有的實例域都是transient,并提供一個readResolve()方法,否則,每次反序列化一個序列化的實例時都會創建一個新的實例。這段話是effectivejava中的描述,我不理解的是為什么僅僅加上implementsSerializable不行呢,反序列化一個序列化的實例時會創建一個新的實例?--補充問題:關于這種單例模式有一種評論如下:這種方式基于classloder機制避免了多線程的同步問題,不過,instance在類裝載時就實例化,雖然導致類裝載的原因有很多種,在單例模式中大多數都是調用getInstance方法,但是也不能確定有其他的方式(或者其他的靜態方法)導致類裝載,這時候初始化instance顯然沒有達到lazyloading的效果。這里的其他方式還可以是什么?
查看完整描述

2 回答

?
慕蓋茨4494581

TA貢獻1850條經驗 獲得超11個贊

1為什么僅僅加上implementsserializable不行
這種方式的單例模式構建的基礎是封裝性,如何實現單例呢?由于構造函數變為了私有,外部無法構造,只能通過Singleton2.getInstance()來獲取,這樣實現了單列,但是序列化時是這樣嗎?序列對象如何知道調用getInstance()來獲取對象呢?我們來看看java底層序列化的實現,打開JDK中類ObjectStreamClass(這個類是負責序列化類對象的)
privatestaticObjectStreamField[]getSerialFields(Classcl)
throwsInvalidClassException
{
ObjectStreamField[]fields;
if(Serializable.class.isAssignableFrom(cl)&&
!Externalizable.class.isAssignableFrom(cl)&&
!Proxy.isProxyClass(cl)&&
!cl.isInterface())
{
if((fields=getDeclaredSerialFields(cl))==null){
fields=getDefaultSerialFields(cl);
}
Arrays.sort(fields);
}else{
fields=NO_FIELDS;
}
returnfields;
}
再往下跟蹤可以明顯看出他是用反射方式來序列化,用反射方式,不是調用getinstance(),當然單例就失效了
2每次反序列化一個序列化的實例時都會創建一個新的實例
由于反序列化時也是用反射,所有當然每一個對象會創建一個新的實例
                            
查看完整回答
反對 回復 2019-04-13
  • 2 回答
  • 0 關注
  • 356 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號