8
public void addAllAnimals(ArrayList<? extends Animal> animalLikeList){

 // I need to add animal objects (eg Dog, Cat that extends Animal) to animalLikeList.

}

? extends Animalの不明なサブタイプを表すため、直接追加できないことはわかっていAnimalます。私の質問は次のとおりです。またはオブジェクトのサブタイプへの

方法(間接的な方法)はありませんか?addaddAllAnimalAnimalanimalLikeList

4

6 に答える 6

9

いいえ、直接的な合法的な方法はありません (安全でない型のキャストは別として)。superではなく、で宣言されたジェネリック コレクションにのみ要素を追加できますextendsこれは、 Effective Java, 2nd Edition , Item 28で Josh Bloch によって一般化された頭字語PECS (Producer - Extends, Consumer - Super) で覚えやすいかもしれません。

実際、あなたが求めているように見えるものは、直接的な意味をなさないようです. AList<? extends Animal>は、たとえば aList<Dog>または aにすることができますList<Cat>Dog前者は要素のみを受け入れることができ、後者はCats のみを受け入れることができます。また、Java ではジェネリック (非具体化可能) 型をインスタンス化できないため、実行時に犬のリストを扱っていることを認識しておく必要があります。そのため、犬をリストに追加しようとするだけです (猫の場合はその逆)。つまり、追加するオブジェクトをローカルで静的に作成することはできません。一般的な方法でオブジェクトを取得する必要があります。これを行う最も簡単な方法は、要素をジェネリック パラメータとして渡すことです。したがって、これを行うことは可能で安全です:

public <E extends Animal> void addAllAnimals(List<E> animalLikeList, E animal) {
    animalLikeList.add(animal);
}

List<Dog> dogs = new ArrayList<Dog>();
List<Cat> cats = new ArrayList<Cat>();

addAllAnimals(dogs, new Dog());
addAllAnimals(cats, new Cat());

このメソッドはジェネリックであり、名前付きの型パラメーターを使用することに注意してください。これにより、リストの実際のジェネリック型は、リストに追加される要素の型と同じになります。

一度に複数のオブジェクトを追加するには、Eパラメータを aに簡単に置き換えることができます。Collection<E>

于 2012-06-20T12:46:28.573 に答える
4

私の質問は: Animal または Animal オブジェクトの SubType を animalLikeList に追加または追加する方法 (間接的な方法) はありませんか?

署名を変更しないわけではありませんが、それには正当な理由があります。そのリストに値を追加したいとしますDog...しかし、論理的には猫のリストだとします:

ArrayList<Cat> cats = new ArrayList<Cat>();
addAllAnimals(cats);

に を追加できないDogはずArrayList<Cat>ですよね?

あらゆる種類の動物をリストに追加できるようにするには、次のものが必要です。

public void addAllAnimals(ArrayList<Animal> animalLikeList) {

また

public void addAllAnimals(ArrayList<? super Animal> animalLikeList) {
于 2012-06-20T12:46:21.880 に答える
1

不変型パラメーターを使用するようにメソッド シグネチャを単純に変更してみませんか?

public void addAllAnimals(ArrayList<Animal> animalLikeList){
   animalLinkedList.add(new Dog());
   animalLinkedList.add(new Cat());

}

それは問題なく動作するはずであり、不変型パラメーターを使用することで、リストからの読み取りまたはリストへの書き込みが許可され、サブタイプのポリモーフィズムの規則により、必要なあらゆる種類の動物を含めることができます。

犬のリストや猫のリストを渡す代わりに、動物のリストをメソッドに渡します。

于 2012-06-20T13:01:53.617 に答える
0
ArraList<anything extends animal> list= new ArrayList<anything extends animal>();


addAllAnimals(list);

これは完全に有効です。メソッドaddAllAnimalsは、Animalのサブタイプを含むことを宣言するarrayListを受け入れます。

また、オブジェクト/リストを追加するために、Animalのサブタイプである任意のオブジェクト/リストを作成できます。

于 2012-06-20T12:49:08.613 に答える
0

一般的なコレクションで addAll を行う非一般的な方法を使用できます

public void testExtends(ArrayList<? extends Parent> list) throws Exception {
    /*  list.add(new Child());
        list.add(new Parent());
        list.add(new GrandParent());
        // can not add
        */
        /**
         * Unsafe collection way
         */
        ArrayList list2=new ArrayList();
        list.addAll(list2);
    }
于 2014-05-20T12:13:03.440 に答える
0

タイプセーフな方法ではありません...

1 つのアイデアは、署名を次のように変更することです。

public static <T extends Animal> void addAllAnimals(ArrayList<? super T> list){}

T または T のサブタイプを T のリストに追加できます...

于 2012-06-20T12:56:19.380 に答える