使用带有Lists.partition和嵌套泛型类型的通配符

时间:2014-02-17 20:09:18

标签: java generics

我正在使用Lists.partition中的Google Guava,虽然我觉得这是关于Java中泛型的一般性问题。

我可以这样做:

public void doSomething(List<DataBean> ids) {
    List<List<DataBean>> lists = Lists.partition(ids, MAX_ITEMS);

为什么我不能这样做?

public void doSomething(List<? extends DataBean> ids) {
    List<List<? extends DataBean>> lists = Lists.partition(ids, MAX_ITEMS);

我收到以下恭维错误:

Type mismatch: cannot convert from List<List<capture#1-of ? extends DataBean>> to List<List<? extends DataBean>>

2 个答案:

答案 0 :(得分:3)

您需要绑定类型以使其始终匹配。否则,?的{​​{1}}与lists的{​​{1}}无关。您可以使用命名类型参数声明泛型方法,而不是使用通配符的通用参数:

?

答案 1 :(得分:2)

partition方法声明为

public static <T> List<List<T>> partition(List<T> list, int size) 

由于泛型类型变量T的声明,该方法变为通用,并且类型变量捕获所使用的类型参数。您使用? extends DataBean作为类型参数,因此据说可以在T中捕获。

所以现在T真的是cap#1 of ? extends DataBean。并且该方法设置为返回该值。换句话说,对于您的调用,它看起来像

public static List<List<cap#1 of ? extends DataBean>> partition(List<cap#1 of ? extends DataBean> list, int size) {

捕获可以是扩展DataBean的任何类型。我们假设它是一种名为SubBean的类型。该方法在概念上(实际上,捕获是真实类型),返回

List<List<SubBean>>

但是您尝试将其返回值分配给类型为

的变量
List<List<? extends DataBean>> 

但是因为this,即。嵌套的泛型类型不能很好地协同工作,您无法将List<List<SubBean>>分配给List<List<? extends DataBean>>

作为上一个链接建议的解决方案,您可以将声明更改为

public void doSomething(List<? extends DataBean> ids) {
    List<? extends List<? extends DataBean>> lists = partition(ids, 3);
}

但是如果有solutions like Ted's.

,我建议不要使用通配符