1

このタイプでAppleのスーパータイプを追加できると想定されている場合、新しいオブジェクトをリストに追加できないのはなぜですか?

import java.util.List;
import java.util.ArrayList;
class Apple{}
public class Macintosh extends Apple {
    public static void main(String[] munch){
        List<Apple> a = new ArrayList<Apple>();
        basket(a);
    }
    static void basket(List<? super Apple> list){ list.add(new Object());}
}

引数を List リストに変更すると、もちろん動作します:s


class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}
public class Mixer<A extends Animal>{
    public <C extends Cat> Mixer<? super Dog> useMe(A a, C c){
        return new Mixer<Animal>();
    }
}

以前のケースでコンパイラがオブジェクトのクラスについて知らなかった場合、なぜ私たちはリターン時に Mixer を使用できるのでしょうか?¿

4

3 に答える 3

0

Appleとそのサブタイプ以外のものをに追加することはできませんList<? super Apple>。「任意のタイプ」ではなく「何らかのタイプ」を意味します。これは、AppleまたはAppleのスーパータイプのいずれかであるいくつかのタイプのインスタンスのリストであり、正確なタイプを知る方法はありません。意味。

可能であれば、これらの制約を回避することをお勧めします。これらの制約はあまり役に立たず、混乱を招きやすいものです。

于 2012-10-18T13:08:01.793 に答える
0

Apple 以外のものを List of Apples に追加しようとしています (Object は Apple のサブクラスではありません)。したがって、コンパイルエラー。

于 2012-10-18T12:22:38.080 に答える
0

他の人が指摘したように、ワイルドカード型は存在量化された型であり、普遍的に量化されたものではありません。これは、ワイルドカードを含む型の変数を使用する場合、書き込み時に任意の一致する型を割り当てることができますが、変数から読み取るときに特定の型を想定することはできないことを意味します。書くときはあなたが選択をコントロールしますが、読むときは他の人があなたのために選択します。

詳細はこちら

  • 書くときは完全に制御できます。returnメソッドの戻り値は、ステートメントの本体内に書き込まれます。そのパラメーターは、メソッドを呼び出す場所に書き込まれます。return特定の型をワイルドカードステートメントに割り当てたり、特定の型をワイルドカード メソッドのパラメーターに渡すことができます。

  • 選択は読書時に強制されます。メソッドの戻り値は、メソッドを呼び出した場所で読み取られます。そのパラメーターは、メソッドを定義する本体内で読み取られます。basket()渡された を使用しようとすると、内部で困難に直面しlistます。

引数を List リストに変更すると、もちろん動作します:s

それはまったく別の話です。List生タイプです。自分自身を発見したように、生の型を使用する場合、Orangeまたはその他Objectを a に追加するなど、安全でないことを行うことができます。List<Apple>Java は主に下位互換性などの歴史的な理由から生の型をサポートしています。それらは設計上不健全です。この方法で生の型を使用すると、ClassCastException後で sを取得する可能性があります。

    List<Apple> a = new ArrayList<Apple>();
    basket(a);
    for (Apple apple : a) {     // Is not assignable to Apple, throws ClassCastException
        System.out.println(apple);
    }
于 2012-10-19T15:23:53.130 に答える