当不清楚使用哪个泛型参数时,如何使用泛型 Java 类的对象?

问题描述 投票:0回答:1

我有以下问题:

我声明了一个接口 (

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);

一切正常。 但我需要以某种方式使用现有的结果集对象。

java generics polymorphism
1个回答
0
投票

你说这个方法必须处理所有结果类型,但是,你的方法是字面上称为

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));
}
© www.soinside.com 2019 - 2024. All rights reserved.