通用接口:
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
或String
替换Date
不是问题。
按如下方式调用getScore()
方法也有效:
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)
,因为它无法处理对象参数。
在这一点上,我不知道如何解决这个问题。我想保持实现类的接口和签名及其具体类型。如果无法进行类型转换或抛出异常,那就没关系。
答案 0 :(得分:8)
你想要类型安全而不想要它之间存在冲突,所以你只需要在它们之间做出决定。使用getScore
参数调用Object
显然是类型不安全的。
现在,如果您只是想要一个类型不安全的技巧来解决编译器/运行时错误,您可以将列表声明为List<Matcher>
,这意味着您将从中检索原始Matcher
然后,您将被允许通过Object
。但将获取未经检查的强制转换编译器警告。
答案 1 :(得分: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);
}
}