2010-08-11 28 views
0

我遇到了不同類加載器加載的枚舉類型的奇怪行爲。在公共庫我有枚舉定義(類似於以下):EnumMap與不同類加載器的鍵的奇怪行爲

enum MyEnumType { VAL_1, VAL_2, VAL_3 }; 

我有這產生以下地圖並將其註冊爲某種系統中的全球第一應用(註冊號爲只爲了簡化符號) :

final Map<MyEnumType, String> map = new EnumMap<MyEnumType, String>(MyEnumType.class); 
map.put(MyEnumType.VAL_1, "value 1"); 
map.put(MyEnumType.VAL_2, "value 2"); 
map.put(MyEnumType.VAL_3, "value 3"); 
GLOBAL_SYSTEM_MAP = Collections.unmodifiableMap(map); 

第二應用(具有不同的類加載器)執行以下操作:

String value = GLOBAL_SYSTEM_MAP.get(MyEnumType.VAL_1); 

並接收空值。我使用調試器檢查了GLOBAL_SYSTEM_MAP是否正確,包含適當的值,但get()方法仍然沒有返回任何正確的值。

我懷疑這個原因可能與兩個應用程序使用的不同類加載器連接來加載MyEnumType類型。但另一方面,枚舉的equals()方法可能爲這種情況做好準備,不是嗎?所以,也許EnumMap.get()實現使用==而不是equals()? (但我相當懷疑)我也嘗試用HashMap替換EnumMap,但是這也沒有解決問題。

回答

2

EnumMap檢查您傳入的密鑰的實際類別與其創建的枚舉的類別相對。如果它們不同,get將返回null。由於您使用不同的類加載器兩次加載MyEnum類,因此該類將有所不同。

修正是爲兩個應用程序安排使用MyEnum類的共享實例。

1

enum不同的類加載器加載的值不應該是==equals。如果將來自不同類加載器的具有相同名稱的不同類同等對待,則通常應該會出現某種錯誤。是GLOBAL_SYSTEM_MAPMap<MyEnumType,String>Map<?,String>(或類似)的類型?

隱藏錯誤的一個可能原因是某些類加載器不會首先委託給它們的父代(IIRC,打破了EE規範推薦的Java SE規範)。這會導致所有問題。