2

次のインターフェースがあります

public interface Splitter<T, V> {
    V[] split(T arg);
}

以下は、スプリッターの実装を取得するために使用しているファクトリ メソッドの実装です。

ファクトリ メソッドの実装

public static <T, V> Splitter<T, V> getSplitter(Class<T> key1, Class<V> key2) {

    if (key1 == Company.class && key2 == Department.class)
        return (Splitter<T, V>) new CompanySplitterImpl();

    // more cases
}

以下は、正常にコンパイルされるクライアント側での私の呼び出しです

Splitter<Company, Department> split = getSplitter(Company.class, Department.class);

クライアント側のコードと実装との密結合を避けたい。ハードコーディングされた Type パラメータを回避する方法はありますか。つまりSplitter<Company, Department>、呼び出し側で Company と Department ( ) を使用せず、代わりに変数を使用する方法はありますか? 外部プロパティ ファイルからロードできる方法はありますか?

参考までに: Java での実現可能性についてはよくわかりません。

4

4 に答える 4

1

それらをリストできる単純なマップクラスを作成できます:

public final class SplitterMap {

    private final List<SplitterType<?, ?>> list = new ArrayList<>();

    private class SplitterType<T, V> {

        private final Class<T> key1;
        private final Class<V> key2;
        private final Class<? extends Splitter<T, V>> clazz;

        private SplitterType(Class<?> key1, Class<?> key2, Class<? extends Splitter<T, V> clazz) {
            this.key1 = key1;
            this.key2 = key2;
            this.clazz = clazz;
        }

        private boolean matches(Class<?> key1, Class<?> key2) {
            return this.key1 == key1 && this.key2 == key2;
        }
    }

    public <T, V> void put(Class<T> key1, Class<V> key2, Class<? extends Splitter<T, V> clazz) {
        list.add(new SplitterType<T, V>(key1, key2, clazz));
    }

    public <T, V> Splitter<T, V> get(Class<T> key1, Class<V> key2) {
        for (SplitterType<?, ?> type : list) {
            if (type.matches(key1, key2)) {
                try {
                    return ((SplitterType<T, V>) type).clazz.newInstance();
                } catch (Exception e) {
                }
            }
        }
        return null; // not found
    }
}

次に、次のようにします。

SplitterMap map = new SplitterMap();
map.put(Company.class, Department.class, CompanySplitterImpl.class);
Splitter<Company, Department> splitter = map.get(Company.class, Department.class);
于 2015-04-18T10:26:43.943 に答える
0

まず、次のようなものが欲しいと思います

Splitter<Company, Department> s = Splitters.getSplitter()

これは、反射なしでは不可能です。

  1. タイプ消去
  2. 戻り値の型のオーバーロードは Java ではまだ利用できません

次に、FactoryMethod パターンを悪用しています。次のようになります。

interface Splitter<T, V> {
    V[] split(T arg);
}

interface SplitterFactory {
    <T, V> Splitter<T, V> getSplitter();
}

class CompanySplitterFactory implements SplitterFactory {
    @Override
    public Splitter<Company, Department> getSplitter() {
        return new CompanySplitterImpl();
    }
}
于 2015-04-18T10:51:44.320 に答える
0

良い方法ではありませんが、1つの方法は次のとおりです。

String companyClass = "Company";
String departmentClass = "Department";
Splitter split = getSplitter(Class.forName(companyClass), Class.forName(departmentClass));//raw splitter
System.out.println(split.split(new Company()));//you could use reflection here to create instance from companyClass String.
于 2015-04-18T09:38:38.303 に答える