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>>)
您能否解释一下为什么会这样,我该如何解决?
参考方案
您需要声明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>
的列表)。
请注意,进行此编译需要使用双通配符。 List<KeywordMetrics<BingKeywordIdentifier>>
是List<? extends KeywordMetrics<? extends KeywordIdentifier>>
,但不是List<KeywordMetrics<? extends KeywordIdentifier>>
。
当我写下面的代码时,编译器说 无法从ArrayList<String>转换为List<Comparable>private List<Comparable> get(){ return new ArrayList<String>(); } 但是当我用通配符编写返回类型时,代码会编译。private List&l…
用glassfish服务器进行struts2会话维护 - java在我的应用程序中,有5分钟的会话超时。<session-config> <session-properties> <property name="timeoutSeconds" value="300"></property> </session-properties…
Java中的“ <<”运算符 - java最喜欢的语句来自Java的Character类:(1 << Character.PARAGRAPH_SEPARATOR)) >> type PARAGRAPH_SEPARATOR是字节,type是整数。这句话中的操作员,他们做什么?如何以及在哪里可以使用这些运算符?这是oracles java.lang.Character文档。该类中…
合并List <T>和List <Optional <T >> - java鉴于: List<Integer> integers = new ArrayList<>(Arrays.asList( 10, 12 )); List<Optional<Integer>> optionalIntegers = Arrays.asList( Optional.of(5), Optional.em…
展平地图中的列表列表 - java我有订单流(来源是订单列表)。每个订单都有一个客户和一个OrderLine列表。我要实现的目标是在一张简单的列表中以客户为关键的地图,并将属于该客户的所有订单行作为值。现在,通过执行以下操作,我现在管理的内容返回了Map<Customer>, List<Set<OrderLine>>>:orders .collect…