2

この状況を修正する方法はあります (可能な限りシナリオを単純化しようとしました):

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

ジェネリックでこれを行う方法があるかどうかはわかりませんが、

4

1 に答える 1

7

これが意味することは、2 つのコレクションが同じ型境界を持つことを証明できないということです。

    CollectionGeneric<? extends Animal> animalsCollectionGeneric = 
             new CollectionGeneric<Animal>(); 
    List<? extends Animal> animals = getAnimals()

最初のものは実行時にCollectionGeneric<Tiger>、2 番目のものはList<Gnu>. それらを混在させると、型の安全性が失われることになります ( carnage は言うまでもありません)。

したがって、これら2つが関連していることをコンパイラーに証明する必要があるため、一般的な署名は次のようになります。

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);
于 2009-07-10T11:15:14.553 に答える