[英]Java Map of References to Singletons
我想創建一個單例類的映射,我可以通過交叉引用訪問該映射以響應特定的請求。 我已經實現了以下內容,但是無法獲取可以調用getInstance()的實際引用。
Map<Integer, Class<? extends Thing>> xref = new HashMap<Integer, Class<? extends Thing>>();
xref.put(1, ThingOne.class);
xref.put(2, ThingTwo.class);
Class<? extends Thing> t = xref.get(1);
最終再做類似...
something.perform(arg1, arg2);
無法弄清楚如何從“ t”轉換為“ something”,或者如果按照我的編碼方式,這是否可行。 我嘗試調用.cast(Thing.class).getInstance(),但遇到了Cast異常。 還嘗試了反射以獲得getInstance()方法,但是那里也沒有運氣。
可能是我完全走錯了路。 給定1..n種可能的功能,該解決方案的任何給定實例可能只需要其中的一個子集。 另外,我想輕松地添加/刪除類,並在啟動時通過config和一堆對象實例化來管理接口。
謝謝!!!
我不太了解您創建此地圖的目的。 從您編寫的內容來看,您似乎可以簡單地將靜態的getInstance()
方法(返回單例)放在每個相關的類上。 或更瑣碎的是:將每個共享實例作為其類的靜態final字段。
如果必須使用地圖,請不要使用整數作為鍵。 類是鍵,其實例是值。 就像是:
private static final Map<Class<?>,Object> singletons = new HashMap<>();
public static synchronized <T> T getSingleton(Class<T> klass) {
Object obj = singletons.get(klass);
if (obj == null) {
try {
obj = klass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
singletons.put(klass, obj);
}
return klass.cast(obj);
}
那里的創建代碼很棘手,需要一個公共的無參數構造函數。 您也可以通過反射在每個類上調用一個靜態的,專門命名的方法來創建所需的實例(“ createInstance”),該實例可能會更靈活一些,但是當您這樣做時,它再次詢問為什么要打擾地圖,什么時候可以直接在類上調用方法?
映射的一種有趣的可能性是提供創建實例的功能。 使用Java 8語法(導入java.util.function.Supplier
):
private static final Map<Class<?>,Object> singletons = new HashMap<>();
public static synchronized <T> T getSingleton(Class<T> klass) {
Object obj = singletons.get(klass);
if (obj instanceof Supplier) {
obj = ((Supplier<?>)obj).get();
singletons.put(klass, obj);
}
return klass.cast(obj);
}
public static synchronized <T> void declareSingleton(Class<T> klass, Supplier<T> supplier) {
if (Supplier.class.isAssignableFrom(klass)) {
// prevent Supplier<Supplier<?>> weirdness;
// could use separate maps if those are really needed
throw new UnsupportedOperationException();
}
singletons.put(klass, supplier);
}
static {
// add creation expressions for several classes;
// instances will not be created until needed
declareSingleton(ThingOne.class, () -> new ThingOne());
declareSingleton(ThingTwo.class, () -> new ThingTwo(123));
}
我不確定這是否是您想要的,但其中可能包含一些想法。
編輯:我剛剛意識到使用類本身作為鍵的問題:即使在特定程序運行期間不需要類,它也會導致類被加載。 使用String鍵可以避免加載不需要的類,但會增加脆弱性。 這是反對將地圖用於所有這些的另一個論點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.