單例大家都不陌生,程式從開啟到死亡過程中只能存在乙個例項,即存在不可建立,今天給大家介紹一種打破這種模式的方法,在程式執行中建立無數個單例例項物件。
關於單例模式模糊或者不懂的可以參考c#單例模式
上文我們講到了反射的基本操作,例項化物件、屬性、方法、特性等操作,可以參考c#反射
咱們切入正題,單例有兩種,一種是程式載入時建立,一種是使用時建立,我們這裡主要是建立乙個載入時建立的單例。我們通過反射來破壞這個單例,建立單例物件
class singleton
public static singleton singl()
return inntleton;
}}
然後通過反射建立這個單例物件並且對比
//呼叫私有方法建構函式
var ass = assembly.load("textcord");
var type = ass.gettype("textcord.singleton");
var singletoncreate = activator.createinstance(type, true);
var singleton = singleton.singl();
console.writeline(object.referenceequals(singleton, singleton.singl()));//true
console.writeline(object.referenceequals(singleton, singletoncreate));//false
class genclass
}
呼叫
var ass = assembly.load("textcord");
//反射呼叫泛型
var type_q = ass.gettype("textcord.genclass`1");
var typemake = type_q.makegenerictype(new type );
var genclass = activator.createinstance(typemake);
var note = typemake.getmethod("note",new type );
note.invoke(genclass, new object );
這裡有幾個重要的部分
我們在獲取這個泛型的時候後面跟一些字元"`1",那麼這個是什麼意思呢?其實這個就是我們編譯**成il的時候,系統指定的乙個類似佔位符的東西,一般來說乙個引數就是"`1",tclass兩個就是"`2"。
第二個注意的地方就是,我們初始化這個t的時候需要呼叫一下makegenerictype()方法,用於初始化型別t,就好像我們new一樣
//如同這樣
var genclass = new genclass();
第三個主要的就是,我們動態呼叫方法,我們一般在createinstance的時候就是建立反射物件的例項,通過強轉或者使用動態型別呼叫方法,這裡我們是通過動態的方式呼叫,示例如下
//反射呼叫泛型
var type_q = ass.gettype("textcord.genclass`1");
var typemake = type_q.makegenerictype(new type );
var genclass = activator.createinstance(typemake);
var note = typemake.getmethod("note",new type );
note.invoke(genclass, new object );
//強轉
genclassy = (genclass)activator.createinstance(typemake);
y.note("yyyyy");
//動態型別
dynamic d = activator.createinstance(typemake);
d.note("ddddd");
readResolve 解決反射破壞單例
具體的操作和測試在單例的部落格中都有提到 單例模式的幾種寫法 單例的寫法和測試結果此片文章不再演示,直接去找readresolve 是怎樣防止破壞單例的。在測試 中用到了 objectinputstream 進入到這個 中,找到 片段 走到readobject 方法中。在readobject 方法中...
反射機制會破壞單例模式嘛
現在已經標準的實現了單例模式 單檢查鎖,雙檢查鎖,列舉 如果我們通過反射機制呼叫,是否會產生多個例項,即破壞了單例模式。反射模式,呼叫方法是不會破壞單例模式,因為反射方法同樣受鎖 邏輯的保護。呼叫建構函式會破壞單例模式,因為構造方法只是private 修飾,防止外部類訪問,但是反射方法訪問,不受限制...
防止利用暴力反射破壞單例模式
單例模式的實現是將構造私有化,然後內部維護乙個物件,但是還是可以通過暴力反射建立多個例項,如下 我以上篇文章講的靜態內部類方式實現單例模式為例 package com.hy.practice import sun.security.jca.getinstance author hy classnam...