私はJavaジェネリックを怒鳴る非常に基本的な質問があります。List<Number>
とはどちらList<? extends Number>
も均質だと思いました。私は正しいですか、それとも私が見逃している基本的な何かがありますか?
3 に答える
ジェネリック型はより衒学的です。
<? extends Number>
番号または不明なサブクラスを意味します。このような値を取得すると、になりますがNumber
、どちらが有効かわからないため、このタイプの値を指定することはできません。
違いは引数と戻り値にあります。
List<Number> numbers = new ArrayList<Number>();
Number n = 1;
numbers.add(n); // ok.
n = numbers.get(0); // ok
numbers.add(1); // ok.
List<? extends Number> numbers2 = new ArrayList<Double>();
numbers2.add(n); // not ok
n = numbers2.get(0); // ok
List<? super Number> numbers3 = new ArrayList<Serializable>();
numbers3.add(n); // ok
n = numbers3.get(0); // not ok.
super
タイプがスーパータイプである可能性があることを示すために、いくつかの場所で使用されます。例えば
コレクションでは、このメソッドは、コンパレータが同じタイプまたは任意のスーパータイプを比較できる必要があることを示しています。
public static <T> void sort(List<T> list, Comparator<? super T> c)
これはあなたが持つことができることを意味します
Comparator<Number> comparesAnyNumbers = ...
List<Integer> ints = ...
Collections.sort(ints, comparesAnyNumbers);
ジェネリックスはコンパイル時の言語機能です。つまり、ランタイムには存在しません。ジェネリックメカニズムでは、コンパイル時のチェックでは、それらは均一ではありません。つまり、ジェネリック型でポリモーフィズムを使用する場合です。
以下は、有効な定義のようですが、コンパイル時エラーが発生します。
List<Number> list = new ArrayList <Integer>();
一方
List<? extends Number> list = new ArrayList <Integer>();
有効です。さらに、右側でワイルドカードタイプを使用することはできません。
List list = new ArrayList <? extends Integer>();
コンパイルされません。
List<Number>
Number
-> s(またはのインスタンスNumber
)の リスト
List<? extends Number>
->拡張するタイプをリストしますNumber