1

我需要初始化几个从 XML 定义到 bean 的不同类型的对象。我有目录结构:

data \
|_ plant \
|  |_ pine.xml
|  |_ cucumber.xml
|_ animal \
|  |_dog.xml
|  |_cat.xml
|_ fungus \
...

我想将它有序地存储在二级地图中:一级地图包含二级地图。每个二级地图都包含一种类型的对象(植物/动物/真菌类......)。每个类都扩展了具有一些公共字段和方法(name/getName()/setName()、desc/getDesc()/setDesc()、toString()、equals() 等的 Dict 类。

现在,为了方便创建所有这些对象,我想要工厂方法 Dict.fabricateAll()。这就是问题所在:如何创建二级映射,以便它们具有精确的类型参数。我不想要 HashMap<String, Dict> 但 HashMap<String, Plant>, HashMap<String, Animal> 等。

现在我有以下代码:

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(handle, bob.newInstance(handle));

错误消息:“接口 Map<K,V> 中的方法不能应用于给定类型。必需:字符串,CAP#1 找到:字符串,对象

是的,那 newInstance() 生成对象,可能应该有一些演员,但什么?我不想在这里只使用“(Dict)”,我更喜欢“(植物)”,“(动物)”......视情况而定。怎么做?

4

1 回答 1

1

将对象转换为字典。这就是多态的好处——你不必引用特定的子类。您可以编写仅引用单个基类 Dict 的代码。这给了你:

  • a) 松耦合——对特定子类没有编译时依赖
  • b) 可扩展性 - 您可以添加子类而无需修改此代码。

是的,有一些方法可以实现您的要求(想到一个大的 switch 语句),但我不推荐任何方法。

于 2013-02-24T17:35:02.367 回答