的地圖我需要初始化一個連接對象的XML定義豆類外徑不同的類型。我有目錄結構:地圖不同類型
data \
|_ plant \
| |_ pine.xml
| |_ cucumber.xml
|_ animal \
| |_dog.xml
| |_cat.xml
|_ fungus \
...
我想按順序將其存儲在兩級地圖中:第一級地圖包含第二級地圖。每個二級地圖都包含一種類型的對象(類植物/動物/真菌......)。每個類擴展了具有一些常用字段和方法(名稱/ getName()/ setName(),desc/getDesc()/ setDesc(),toString(),equals()等的Dict類。 ,以方便所有這些對象我想有工廠方法Dict.fabricateAll(創建)這裏的問題是:如何使他們有精確的類型參數創建第二級地圖,我不想HashMap的<字符串,快譯通>但HashMap的<字符串,植物>,HashMap的<字符串,動物>等
現在我有以下代碼:
public static Map<String, Map<String, ? extends Dict>> fabricateAll() {
File topDir = new File(Dict.defDir);
File[] subDirs = topDir.listFiles();
Map<String, Map<String, ? extends Dict>> dicts = new HashMap<>(subDirs.length);
String type;
String handle;
Map<String, ? extends Dict> dict;
for (File subDir : subDirs) {
type = subDir.getName();
File[] xmlFiles = subDir.listFiles(new FilenameFilter() {public boolean accept(File dir, String name) { return name.toLowerCase().endsWith(".xml"); }});
dict = new HashMap<>(xmlFiles.length);
for (File defFile : xmlFiles) {
handle = defFile.getName();
handle = handle.substring(0, handle.lastIndexOf('.')-1);
try {
Class c = Class.forName(type);
Constructor bob = c.getConstructor(Class.forName("java.lang.String"));
dict.put(handle, bob.newInstance(handle));
} catch (Exception e) {
e.printStackTrace();
}
}
dicts.put(type, dict);
}
return dicts;
}
但有一個與線的一個問題: dict.put(手柄,bob.newInstance(手柄));
錯誤消息:「方法把接口Map < K,V >不能被應用到給定的類型的要求:字符串,CAP#1實測值:字符串,對象
是的,這的newInstance()生成對象和或許應該有一些投,但到什麼?我不想只是「(字典)」在這裏,我更喜歡「(植物)」,「(動物)」 ......爲合適的。那怎麼辦?
你返回一個'地圖<字符串,地圖<字符串?擴展Dict >>'。因此,客戶端代碼無法知道地圖是否包含Plant,Cat或其他內容。它只知道它們是Dict的實例。所以把它投給Dict,一切都會好起來的。也就是說,我不會使用反射來做到這一點,而是工廠(每種字典的一個工廠),這將允許做你想做的事情。 – 2013-02-24 17:36:58
但是動物可以運行()而植物不能。如果我將它轉換爲Dict,我不可能首先調用run(),而不是手動投射到Animal。 至於辦法「每一個快譯通工廠」:你的意思是我應該在的,而不是調用每個快譯通亞型和公共靜態編造(字符串處理)'「bob.newInstance(句柄)」做: 字典。 put(handle,c.getMethod(「fabricate」,Class.forName(「java.lang.String」)))? 這給出了相同的錯誤。 – Forseti 2013-02-24 17:56:52
當你有一個Map',你無法知道地圖包含什麼。你所能做的就是測試這個值是植物還是動物的一個實例(使用'instanceof'),並將這個值轉換爲植物或動物。那麼你將Map作爲'Map '獲得了什麼,因爲你將它作爲'Map 返回?擴展Dict>'。你的工廠理念確實是一個解決方案。您將需要返回Plant或Animal(取決於類)的方法,並且您需要地圖的類型爲Map 或Map 類型,具體取決於在目錄中。 –
2013-02-24 18:04:24