的地图我需要初始化一个连接对象的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