readResolve 解決反射破壞單例

2021-10-23 06:53:56 字數 1982 閱讀 9894

具體的操作和測試在單例的部落格中都有提到:單例模式的幾種寫法

單例的寫法和測試結果此片文章不再演示,直接去找readresolve()是怎樣防止破壞單例的。

在測試**中用到了:

objectinputstream()

進入到這個**中,找到**片段

走到readobject()方法中。

在readobject()方法中呼叫readobject0()的方法。在這個方法中斷點除錯進入到switch case方法中如圖:

看一下在這裡呼叫readordinaryobject()方法做了什麼事情。

在這裡又看到了乙個呼叫的方法:isinstantiable(),它又是做的什麼呢?

繼續看,

就是乙個很簡單的方法:

boolean isinstantiable()

就是判斷一下構造方法是否為空,構造方法不為空就返回乙個true。那麼返回的true又是做了什麼,在上面截圖中可以看到。

這裡就可以知道obj的結果了吧!!!

解析:乙個三元運算子告訴我們,在呼叫desc.isinstantiable()這個方法的時候,返回true就進行了desc.newinstance()。只要有無參構造方法就要例項化。

readresolvemethod =

getinheritablemethod

( cl,

"readresolve"

, null, object.class)

;

通過反射的方式找到乙個無參的readresolve.

if

(obj != null &&

handles.

lookupexception

(passhandle)

== null &&

desc.

hasreadresolvemethod()

)if(rep != obj)

else

} handles.

setobject

(passhandle, obj = rep);}

}

還有乙個desc.invokereadresolve(obj)呼叫的方法,進到這個方法,**片段

object invokereadresolve

(object obj)

throws ioexception, unsupportedoperationexception

catch (invocationtargetexception ex)

else

} catch (illegalacces***ception ex)

}else

}

在裡面有這麼一句**return readresolvemethod.invoke(obj, (object) null);由此而知反射呼叫了readresolvemethod()方法。

總結:雖然只是增加了readresolve()方法返回例項解決了單例模式被破壞的問題, 但是實際上例項化了兩次,只不過新建立的物件只是沒有被返回。

反射解決類的複製

假定乙個類,類名是etybase,另乙個類類名是etytwo,etytwo繼承自etybase。現在要求etytwo的屬性值從乙個etybase中複製過來傳統做法是 view code public void copyety etybase from etybase to 這樣子做有幾點不好的地方 ...

單例 序列化和readResolve 方法

說到這個話題,我先丟擲單例的餓漢式寫法 單例 餓漢式 public class hungrysingleton private static final hungrysingleton hungry new hungrysingleton public static hungrysingleton ...

策略模式 反射 解決多重if else if問題

需求 商品有三種折扣價,普通客戶不享受任何優惠,vip客戶享受9折優惠,超級vip客戶享受8折優惠 當沒有用到設計模式時,我們一般會採用下面的方式處理業務 int type 1 if type 1 else if type 2 else if type 3 這樣做的好處是直觀,能以下看懂其中的邏輯關...