我有以下问题:
我声明了一个接口 (
ResultType
) 和一些实现它的类 (PointResult
, TimeResult
, LengthResult
)。
然后我有这些结果类型的通用集合:
public class ResultSet<T extends ResultType> {
private final Class<T> type;
private final HashMap<String, T> resultList;
// Constructor
public ResultSet(Class<T> type) {
this.type = type;
resultList = new HashMap<>();
}
// add participant and result
public void addResult(String athlete, T result) {
resultList.put(athlete, result);
}
// return type of results
public Class<T> getType() {
return type;
}
}
现在,当尝试在另一个对象/方法中添加结果时,例如像这样
public void enterPointResult(ResultSet<?> resultSet, String athlete, int points) {
resultSet.addResult(athlete, new PointResult(points));
}
我收到类似的错误
不兼容的类型:PointResult 无法转换为 capture#1 of ?
我不明白,因为即使我错误地使用了另一种结果类型,由于多态性和接口的使用,也不应该有任何问题。
我还尝试了 if/else(因此是 getType 方法)、
instanceof
等,但没有效果。
但是,当声明并实例化一个新的
ResultSet
时,特别适合像
ResultSet<PointResult> newRes = new ResultSet<>(PointResult.class);
一切正常。 但我需要以某种方式使用现有的结果集对象。
你说这个方法必须处理所有结果类型,但是,你的方法是字面上称为
enterPointResult
。所以,显然,它只能适用于 ResultSet<PointResult>
。因为打电话肯定是疯子:
ResultSet<TimeResult> timeResultSet = ...;
enterPointResult(timeResultSet, "Dick Fosbury", 100.0);
但是,您想要的签名(“可以处理any结果集类型!”)表示您可以这样写。泛型的全部意义在于让类型系统捕获那些毫无意义的代码。
因此,鉴于您想要废话,您不能使用泛型。简单。
抛弃
T
并允许结果集接受任何内容,让用户 instanceof
并让自己变得愚蠢。
或者,修复此处的真正错误,即您希望能够在 TimedResultSet
上设置
point结果 - 确保不再是这种情况。然后,该方法就变成了:
public void enterPointResult(ResultSet<? super PointResult> resultSet, String athlete, int points) {
resultSet.addResult(athlete, new PointResult(points));
}