3

マップを簡単に構築するために実装しただけですMapBuilderが、HashMap.class のインスタンスを取得しようとすると、HashMap.class を使用してそのようなインスタンスを取得できないことが突然わかりました。

違法です!

では、この問題を解決する理由と方法を誰か教えてもらえますか?

MapBuilder は次のとおりです。

import java.util.Map;

public abstract class MapBuilder {

    public static <K, V, T extends Map<K, V>> InnerMapBuilder<T, K, V> start(
            Class<T> clazz) {
        return new InnerMapBuilder<>(clazz);
    }

    public static class InnerMapBuilder<T extends Map<K, V>, K, V> {

        private T target;

        public InnerMapBuilder(Class<T> clazz) {
            try {
                target = clazz.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }

        public InnerMapBuilder<T, K, V> put(K key, V val) {
            target.put(key, val);
            return this;
        }

        public T get() {
            return target;
        }
    }
}

テストコードは以下のとおりです。

public static void main(String[] args) {
    HashMap<String, String> v = start(HashMap<String,String>.class).put("a", "b").get();
    System.out.println(v);
}
4

2 に答える 2

1

Reimeus が言ったように、ジェネリック型のパラメーター化されたクラス型変数を取得することは不可能です。したがって、3 つの選択肢があります。

まず、チェックされていないキャストを使用できます。

Class<? extends Map<String, Integer>> clazz = 
    (Class<? extends Map<String, Integer>>) HashMap.class;

次に、クラスを拡張することでクラスのパラメータを具体化できます(この例では、匿名の内部クラスを使用しています)。

Class<? extends Map<String, Integer>> clazz =
     new HashMap<String, Integer>() {}.getClass();

または 3 番目に良いMapのは、クラスの代わりにインスタンスを取得することstart()です。Classのインスタンスではなくを取得することで、ユーザーの作業を節約することはありません。Map最初に行うことは、そのインスタンスを作成することです。

これを渡すことで、ユーザーはマップの設定を微調整することもできるので (たとえば、 のHashMap場合は負荷係数を設定し、 の場合はTreeMapを指定しますComparator)、いずれにせよより良い代替手段となります。必要に応じて、渡されたときに空であることをアサートできます。

何らかの理由で本当にファクトリが必要な場合は、使用しないでください。Classファクトリとしてはうまく機能しません。作成するインスタンスをカスタマイズできる唯一の方法Classは、クラスをサブクラス化し、新しい引数のないコンストラクタを提供することです。Factory<T>メソッドを持つインターフェイスを作成しT create()Factory<? extends Map<K, V>.

于 2012-10-28T15:39:46.320 に答える
0

まず、startはクラスを取るため、 などのパラメータ化されていないクラスを渡す必要がありますHashMap.class。次に、ジェネリック型を返すMapため、ローカル型も一致させる必要があるため、次を使用します。

Map<String, String> v = start(HashMap.class).put("a", "b").get();
于 2012-10-28T15:14:14.807 に答える