2011-11-21 32 views
1

經過一番考慮之後,我在我的應用程序中實現了緩存,基本上,使用包含Class作爲關鍵字(這是對應於特定緩存實體的類,並從摘要AbstractCache繼承的類)和具體緩存對象從那個班製成,看起來相當方便。Class as Hashtable key - 這是一個好主意嗎?

但是,將Class作爲Hashtable鍵還是應該使用.canonicalName()或類似的東西?

+1

我懷疑使用'Hashtable'作爲緩存並不是最好的選擇。對於緩存,無論如何你通常需要實現自己的同步。否則'ConcurrenctHashMap'可能是一個更好的選擇。 –

+2

除了Peter的評論之外:請參閱Google Guava的Cache實現,該實現提供了併發性和其他一些功能(可選的弱/軟引用,統計信息...)。即使你不使用它,Guava也有一個很好的ClassToInstanceMap,它對你很有用。 –

回答

3

如果你永遠不需要卸載類,它可能不是一個問題。但是由於需求可能因您的代碼運行方式(獨立Java應用程序或部署在Web容器,企業服務器等)而異,因此可能不這樣做。類加載器泄漏是非常令人討厭的錯誤來追蹤和解決。

使用規範名稱似乎是一個更好的解決方案。但請記住另一個挑戰:如果您有多個可能加載相同類的類加載器,那些類仍將被視爲不兼容。您將無法通過其規範名稱來區分它們,而由不同類加載器加載的兩個相同類將產生兩個不同的實例,並且可以在同一個映射中用作鍵。

如果您沒有非常具體的類加載器約束或要求,請使用規範名稱。如果您正在部署除獨立Java應用程序之外的其他任何應用程序,請謹慎行事。

+1

我仍然會使用Class對象。由於不兼容的類導致的ClassCastExceptions可能比classloader泄漏更糟糕,所以最好在這一邊。此外,如果您將該類的實例作爲值存儲在該緩存中,那麼使用規範名稱將無助於班級卸載,因爲無論如何您都需要從地圖中刪除條目。如果你需要這個,使用弱/軟引用鍵和值。 –

+0

@PhilippWendler很好的建議。我只記得我曾經需要一個class-to-something的地圖,並且使用'Class'對象而不是名字。提供了一些方法從緩存中刷新類,以防需要卸載。 –

2

聽起來很好。我過去曾經這樣做過。類實際上是不可變的單例,所以沒有機會使用類的「錯誤」實例。

唯一會遇到問題的是如果涉及多個ClassLoader,但在大多數應用程序中這種情況很少。

相關問題