泛型问题Java

野山羊
public class GetResponse <T extends KeywordIdentifier>{

    private List<KeywordMetrics<T>> metrics = null;


public List<KeywordMetrics<T>> getMetrics(){
        return this.metrics;
    }

    public void setMetrics(List<KeywordMetrics<T>> metrics){
        this.metrics = metrics;
    }
}


public class AdWordsKeywordIdentifier extends KeywordIdentifier {
//body
}
public class BingKeywordIdentifierextends KeywordIdentifier {
//body
}


GetResponse<? extends KeywordIdentifier> result= new GetResponse<AdWordsKeywordIdentifier>();
List<KeywordMetrics<AdWordsKeywordIdentifier>> stats = getGoogleStats();
List<KeywordMetrics<BingKeywordIdentifier>> stats2 = getBingStats();
result.setMetrics(stats);
result.setMetrics(stats2);

result.setMetrics(stats) 方法产生编译错误。

ERROR (The method setMetrics(List<KeywordMetrics<capture#2-of ?extends KeywordIdentifier>>) in the type GetResponse<capture#2-of ?extends KeywordIdentifier> is not applicable for the arguments(List<KeywordMetrics<AdWordsKeywordIdentifier>>)

您能否解释一下为什么会这样,我该如何解决?

乔凡尼·博塔(Giovanni Botta)

您需要声明result它是什么,即GetResponse<AdWordsKeywordIdentifier>

编辑

查看您的更改,我看到了一个大问题。您正在尝试setMetrics使用两种不同类型的两个列表来调用该方法。您根本无法做到这一点。由于GetResponse已使用进行了参数化T,因此列表中元素的类型必须完全T是,即AdWordsKeywordIdentifier BingKeywordIdentifier不能相同。编译器在抱怨,因为GetResponse具有类型参数,? extends KeywordIdentifier并且它可能无法推断出实际的类型参数是什么,因此它不能静态地确保对的方法调用的类型安全setMetrics,即,您将永远无法调用它。

虽然并没有全部丢失。您必须做出选择:要么让您的通用类保持不变,然后始终强制强类型化,要么可以使该类不是通用类,metrics并按如下所示修改字段:

class GetResponse {

  private List<? extends KeywordMetrics<? extends KeywordIdentifier>> metrics = null;

  public List<? extends KeywordMetrics<? extends KeywordIdentifier>> getMetrics() {
    return this.metrics;
  }

  public void setMetrics(List<? extends KeywordMetrics<? extends KeywordIdentifier>> metrics) {
    this.metrics = metrics;
  }
}

现在仅适用于您的原始代码段:

GetResponse result = new GetResponse();
List<KeywordMetrics<AdWordsKeywordIdentifier>> stats = new ArrayList<>();
List<KeywordMetrics<BingKeywordIdentifier>> stats2 = new ArrayList<>();    result.setMetrics(stats);
result.setMetrics(stats2);

这完全取决于您要实现的目标。上面的代码仍然是类型安全的。由于您说过要“通用”代码,因此必须放弃在编译时知道列表的确切类型(现在是的列表? extends KeywordMetrics<? extends KeywordIdentifier>)。

请注意,进行此编译需要使用双通配符。AList<KeywordMetrics<BingKeywordIdentifier>> 是一个, List<? extends KeywordMetrics<? extends KeywordIdentifier>>不是一个 List<KeywordMetrics<? extends KeywordIdentifier>>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章