1

XML 定義から Bean まで、さまざまなタイプのオブジェクトをいくつか初期化する必要があります。私はディレクトリ構造を持っています:

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

2 レベルのマップに整然と格納したい: 最初のレベルのマップは 2 番目のレベルのマップを保持します。各第 2 レベルのマップは、1 つのタイプ (植物/動物/菌類のクラス) のオブジェクトを保持します。各クラスは、いくつかの共通フィールドとメソッド (name/getName()/setName()、desc/getDesc()/setDesc()、toString()、equals() など) を持つ Dict クラスを拡張します。

ここで、このすべてのオブジェクトの作成を容易にするために、ファクトリ メソッド Dict.fabricateAll() が必要です。そして、ここに問題があります: 正確な型パラメーターを持つように、第 2 レベルのマップを作成する方法です。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)」だけではなく、「(Plant)」、「(Animal)」などを適切に使用したいと思います。どうやってするか?

4

1 に答える 1

1

オブジェクトを Dict にキャストします。これが多態性の利点です。特定のサブクラスを参照する必要はありません。単一の基本クラス Dict への参照のみを使用してコードを記述できます。これにより、以下が得られます。

  • a) 疎結合 - 特定のサブクラスへのコンパイル時の依存関係なし
  • b) 拡張性 - このコードを変更せずにサブクラスを追加できます。

はい、あなたが要求したことを達成する方法はあります (大きな switch ステートメントが頭に浮かびます) が、私が推奨する方法はありません。

于 2013-02-24T17:35:02.367 に答える