泛型问题java

时间:2014-05-09 13:16:21

标签: java generics inheritance

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

请你解释一下为什么会这样,以及如何解决它?

2 个答案:

答案 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 = ....

应该修复它。