我正在研究一個(簡單)緩存解決方案,其中一個服務可以從一個緩存映射請求緩存對象。一個Cache對象的工作原理與Map一樣,具有一個鍵和一個值以及訪問和存儲對象的方法。Java泛型 - 映射(鍵入)映射
我想出了以下解決方案,但正如您所看到的,它包含一個轉換(因爲get()無法知道嵌套對象的類型應該是什麼)。
private final Map<String, Cache<?, ?>> caches = new HashMap<String, Cache<?, ?>>();
public <K, V> Cache<K, V> getOrCreateCache(String identifier) {
if (caches.containsKey(identifier)) {
return (Cache<K, V>) caches.get(identifier);
} else {
Cache<K, V> cache = new CacheImpl<K, V>();
caches.put(identifier, cache);
return cache;
}
}
private void test() {
Cache<String, String> strCache = getOrCreateCache("string cache");
strCache.set("key", "value");
}
現在,我的問題:
- 這是一個 '安全' 的做法,只要ClassCastExceptions異常得到妥善處理? (可能會抓住那些並將它們打包成自定義異常類)
- 是否存在「安全」選擇?一個泛型,如果可能的話,因爲我喜歡他們,不喜歡演員。
- (並不直接相關)這是線程安全嗎?我不假設,但是,我不是線程專家。僅僅使整個方法同步就足夠了,還是會(有六個客戶端)造成太多開銷/鎖定?有沒有一個很好的解決方案?
編輯:Woo,很多答案,謝謝!在這裏編輯來描述我在實際測試時發現的一個奇怪現象:
Cache<String, String> someCache = service.getOrCreateCache(cacheIdentifier);
someCache.set("asdf", "sdfa");
Cache<String, Integer> someCacheRetrievedAgain = service.getOrCreateCache(cacheIdentifier);
System.out.println(someCacheRetrievedAgain.get("asdf")); // prints "sdfa". No errors whatsoever. Odd.
我喜歡ArrayList的擴展來快速組成一個排序的標識符,很好的技巧,應該記住它。我會嘗試你的解決方案。 – fwielstra 2011-01-19 09:32:06