有任何方法可以解决这种情况(我尽可能多地尝试简化场景):
public class Test {
public static void main(String[] args) {
/*
* HERE I would like to indicate that the CollectionGeneric can be of
* something that extends Animal (but the constructor doesn't allow
* wildcards)
*/
CollectionGeneric<? extends Animal> animalsCollectionGeneric = new CollectionGeneric<Animal>();
List<? extends Animal> animals = getAnimals();
/* Why I cannt do that? */
animalsCollectionGeneric.setBeans(animals);
}
private static List<? extends Animal> getAnimals() {
return new ArrayList<Dog>();
}
}
class CollectionGeneric<T> {
private List<T> beans;
public List<T> getBeans() {
return (beans != null) ? beans : new ArrayList<T>();
}
public void setBeans(List<T> beans) {
this.beans = beans;
}
}
interface Animal {}
class Dog implements Animal{}
这个场景给了我下一个错误:
The method setBeans(List<capture#2-of ? extends Animal>) in the type
CollectionGeneric<capture#2-of ? extends Animal> is not applicable for
the arguments (List<capture#3-of ? extends Animal>)*
我不确定是否有办法用泛型来做这件事,
答案 0 :(得分:7)
这意味着两个集合无法证明具有相同的类型边界:
CollectionGeneric<? extends Animal> animalsCollectionGeneric =
new CollectionGeneric<Animal>();
List<? extends Animal> animals = getAnimals()
第一个可能在运行时有CollectionGeneric<Tiger>
而第二个有List<Gnu>
。混合这些意味着你失去了类型安全(更不用说大屠杀)。
因此,您需要向编译器证明这两者是相关的,因此您的通用签名应该是:
public void setBeans(List<? extends T> beans) {}
public List<T> getBeans();
用作:
List<? extends Animal> beans = getBeans();
GenericCollection<Animal> animals = new GenericCollection<Animal>();
animals.add(beans);