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>>)
请你解释一下为什么会这样,以及如何解决它?
答案 0 :(得分:6)
您需要声明result
的内容,即GetResponse<AdWordsKeywordIdentifier>
。
修改强>:
看看你的变化,我发现了一个大问题。您正尝试使用两个不同类型的列表调用setMetrics
方法。你根本做不到。由于GetResponse
已使用T
参数化,因此列表中元素的类型必须完全为T
,即AdWordsKeywordIdentifier
或 { {1}},它不能同时存在。编译器抱怨,因为BingKeywordIdentifier
具有类型参数GetResponse
并且它不可能推断实际类型参数是什么,因此它不能静态地确保方法调用{{1}的类型安全性,即你永远不会能够调用它。
但并非所有人都失去了。您必须做出选择:保持您的通用类不变并始终强制执行强类型,或者您可以使该类不通用并修改? extends KeywordIdentifier
字段,如下所示:
setMetrics
现在只适用于原始代码段:
metrics
这完全取决于你想要达到的目标。上面的代码仍然是类型安全的。既然你说你想要你的代码&#34; generic&#34;你必须放弃在编译时知道列表的确切类型(它现在是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>
,但不是 List<KeywordMetrics<BingKeywordIdentifier>>
。
答案 1 :(得分:5)
您没有使用正确的类型参数化声明变量结果。因此,编译器无法保证使用此列表调用setMetrics方法应该有效。
将其更改为
GetResponse<AdWordsKeywordIdentifier> result = ....
应该修复它。