带有通配符的Java泛型

Dav*_*ria 2 java generics bounded-wildcard

有任何方法可以解决这种情况(我尽可能多地尝试简化场景):

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{}
Run Code Online (Sandbox Code Playgroud)

这个场景给了我下一个错误:

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>)*
Run Code Online (Sandbox Code Playgroud)

我不确定是否有办法用泛型,

Rob*_*anu 7

这意味着两个集合不能被证明具有相同的类型边界:

    CollectionGeneric<? extends Animal> animalsCollectionGeneric = 
             new CollectionGeneric<Animal>(); 
    List<? extends Animal> animals = getAnimals()
Run Code Online (Sandbox Code Playgroud)

第一个可能在运行时有CollectionGeneric<Tiger>和第二个List<Gnu>.混合那些意味着你失去了类型安全(更不用说大屠杀).

因此,您需要向编译器证明这两者是相关的,因此您的通用签名应该是:

public void setBeans(List<? extends T> beans) {}
public List<T> getBeans();
Run Code Online (Sandbox Code Playgroud)

用作:

List<? extends Animal> beans = getBeans();
GenericCollection<Animal> animals = new GenericCollection<Animal>();
animals.add(beans);
Run Code Online (Sandbox Code Playgroud)

  • 好答案.请注意,如果您想添加一个addBeans()方法,它可以简单地使用类型为T的对象.Josh Bloch在Google I/O上发表了一篇关于泛型和通配符的演讲.请参阅http://sites.google.com/site/io/effective-java-reloaded (2认同)