20

私は大学で高度なプログラミングのクラスを持っていますが、このコードがどのように機能するかを理解するのに少し苦労しています。

public final class GenericClass<T> {
    private void overloadedMethod(Collection<?> o) {
        System.out.println("Collection<?>");
    }

    private void overloadedMethod(List<Number> o) {
        System.out.println("List<Number>");
    }

    private void overloadedMethod(ArrayList<Integer> o) {
        System.out.println("ArrayList<Integer>");
    }

    public void method(List<T> l) {
        overloadedMethod(l);
    }

    public static void main(String[] args) {
        GenericClass<Integer> test = new GenericClass<Integer>();
        test.method(new ArrayList<Integer>());
    }
}

このコードが "Collection<?>" を出力するのはなぜですか?

4

3 に答える 3

14

の宣言はmethod(List<T> l)、タイプTの境界を指定しません。TがNumberまたはNumberのサブクラスであるという保証はありません。したがって、コンパイラは、このメソッドがを呼び出すことのみを決定できますoverloadedMethod(Collection<?> o)

覚えておいてください:コンパイル後、ジェネリックスに関する情報はクラスファイルで利用できなくなります。

于 2013-03-12T13:04:43.740 に答える
-1

メソッドのオーバーロードを扱うときは、次の 3 つの概念を頭に入れておく必要があります。

  1. 拡幅
  2. ボクシング
  3. Var_args

あなたの問題は拡大している最初のポイントにあります。Javaコンパイラは、これらの概念のそれぞれに上にリストされているのと同じ順序で優先順位を付けますtest.method(new ArrayList<Integer>()); 。優先度が最も高いため、これらのバージョンを呼び出し、他のバージョンは無視します。注: 他の 2 つのメソッドの宣言を に変更すると、優先バージョンであるため、コンパイラもそのバージョンを呼び出します。ArrayList<Integer>()Collection<?>private void overloadedMethod(ArrayList<?> o)private void overloadedMethod(List<?> o)Collection<?>

于 2013-03-12T13:22:43.180 に答える
-1

ジェネリック型を定義するたびに、対応する生の型が自動的に提供されます このメソッド

public void method(List<T> l) {

}

に置き換えています

public void method(List<Object> l) {

}

ワイルドカード型について読むと、List<Number>andList<Object> またはArrayList<Integer>andList<Object>には型関係がないことがわかります。List<Object>のサブタイプであるCollecion<?>ため、このメソッドが呼び出されます。

于 2013-03-12T13:20:23.893 に答える