3

次のメソッド宣言は、

public void testMethod(ArrayList<T extends Animal> list)

public <T extends Animal> void testMethod(ArrayList<T> list)

同じ?

4

2 に答える 2

4

それらは、1 つの重要な点で同じではありません。最初のケースでは、ジェネリック パラメーターはクラスのスコープにバインドされ、メソッドを複数回呼び出しても変化しません。

2 番目のケースでは、ジェネリック パラメーターは、メソッドが呼び出される引数に依存し、個別の呼び出しごとに異なる場合があります。

したがって、このクラスを考えると:

public class MyClass<T extends Animal> {
    public void handleList1(List<T> list) {
       // implementation
    }

    public <U extends Animal> void handleList2(List<U> list) {
        // implementation
    }
}

次のようにインスタンス化します。

MyClass<Bear> test = new MyClass<Bear>();

handleList1タイプのリストでのみ呼び出すことができますBear。一方、次のように呼び出すことができますhandleList2

test.handleList2(new ArrayList<Tiger>);
test.handleList2(new ArrayList<Lion>);
test.handleList2(new ArrayList<Puma>);

そのためのジェネリック パラメータは、メソッドにも指定された引数によって決定されるためです。

于 2013-02-10T16:49:07.897 に答える
3

違いは、前者はコンパイルしないのに対し、後者はコンパイルすることです。それはあなたが求めていたものですか?

次の違いを意味する場合:

public void testMethod (ArrayList <? extends Animal> list)

public <T extends Animal> void testMethod (ArrayList <T> list)

ArrayList違いは、最初のケースでは要素の実際のタイプを参照できないのに対し、2 番目のケースでは参照できることです。

おそらく、次の 2 つのケースを検討すると、違いがより明確になります。

public void testMethod (
    ArrayList <? extends Animal> l1, 
    ArrayList <? extends Animal> l2)

public <T extends Animal> void testMethod (
    ArrayList <T> l1, ArrayList <T> l2)

最初のケースでは、最初の引数はArrayListを拡張する型でAnimalあり、2 番目の引数はを拡張する型Arraylistまたは (おそらく他の) 型ですAnimal

2 番目のケースでは、両方の引数がextends と同じ型ArralListですAnimal

于 2013-02-10T16:50:46.407 に答える