4

通用接口:

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

两个实现类:

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

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

到目前为止一切都很好。替换或不是问题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>,这意味着您将从其中检索原始Matchers,然后您将被允许传入Objects。不过,您收到未经检查的强制转换编译器警告。

于 2012-12-24T21:15:38.630 回答
0

最好使用捕获助手,这样您就可以使用匹配器的参数类型(例如T),value1并且value2将被声明为该类型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 回答