我正在使用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>>
答案 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);
}
,我建议不要使用通配符