4

汎用インターフェース:

public interface Matcher<T> {
    public double getScore(T value1, T value2);
}

2 つの実装クラス:

public StringMatcher implements Matcher<String> {
    public double getScore(String value1, String value2) {...}
}

public DateMatcher implements Matcher<Date> {
    public double getScore(Date value1, Date value2) {...}
}

これまでのところ、すべて問題ありません。orに置き換えTても問題ありません。次のようにメソッドを呼び出しても機能します。StringDategetScore()

Matcher<String> matcher = new StringMatcher();
matcher.getScore("hello", "world");

List未知の があり、その方法Matcherを使用したい場合に問題が発生します。getScore()

public void test() {
    List<Matcher<?>> list = new ArrayList<Matcher<?>>();
    list.add(new StringMatcher());
    list.add(new DateMatcher());

    for (Matcher<?> matcher : list) {
        Object value1;
        Object value2;
        //Setting values value1 & value2 appropriate to the current matcher
        matcher.getScore(value1, value2);
    }
}

matcher.getScore(value1, value2)オブジェクト パラメータを処理できないため、呼び出すことができません。そして、この時点で、これを解決する方法がわかりません。具象型を持つ実装クラスのインターフェイスとシグネチャを保持したいと考えています。型のキャストや例外のスローを回避する方法がない場合は、問題ありません。

4

2 に答える 2

8

タイプ セーフが必要な場合と不要な場合との間に矛盾があるため、どちらかを決定する必要があります。getScore引数を指定して呼び出すObjectことは、明らかに型安全ではありません。

ここで、コンパイラ/ランタイム エラーを回避するためにタイプ セーフでないトリックが必要な場合は、リストを として宣言できます。これは、リストからList<Matcher>Matcherの s を取得し、s を渡すことができることを意味しますObject。ただし、チェックされていないキャストコンパイラの警告が表示されます。

于 2012-12-24T21:15:38.630 に答える
0

キャプチャ ヘルパーを使用するのが最善です。これにより、マッチャーのパラメーター タイプ (たとえばT)を使用でき、そのタイプであるvalue1value2宣言されますT

private <T> double helper(Matcher<T> matcher) {
    T value1;
    T value2;
    //Setting values value1 & value2 appropriate to the current matcher
    return matcher.getScore(val1, val2);
}

public void test()
{
    List<Matcher<?>> list = new ArrayList<Matcher<?>>();
    list.add(new StringMatcher());
    list.add(new DateMatcher());

    for (Matcher<?> matcher : list) {
        helper(matcher);
    }
}
于 2012-12-25T00:01:32.843 に答える