2009-07-19 14 views
2

は、このコードを考えてみましょう:はJavaのジェネリックメソッド質問

public <T> List<T> meth(List<?> type) 
{ 
    System.out.println(type); // 1 
    return new ArrayList<String>(); // 2 
} 

それはそのリストが必要になると言って、2行目でコンパイルされません。今

、変わったの場合:それはコンパイルん

public <T> List<?> meth(List<T> type) 
{ 
    System.out.println(type); // 1 
    return new ArrayList<String>(); // 2 
} 

。どうして?ワイルドカードを使用する場合、Tにジェネリック型を宣言してワイルドカードを使用することの違いは、ワイルドカードを使用すると、コレクションに新しい要素を追加できないということでした。 <?>は、リストのサブタイプを返すことができるのはなぜですか?私はここに何かが欠けている、明白なルールとそれがどのように適用されているのですか?

+0

元の目標は何ですか?あなたの方法で何を達成したいですか? – akarnokd

+0

何も実際には、これはプロジェクトの一部ではない、私はちょうどJavaの一般的なメソッドを理解したい。私はこれを今読んでいるhttp://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf – andandandand

答えて

4

違いは戻り値の型宣言です。 List<String>List<T>のサブタイプではありませんが、サブタイプはList<?>です。次の文は有効ですので

List<?>は、その型の変数に関する仮定を行いません:

List<?> l0 = new ArrayList<String>(); 
List<?> l1 = new ArrayList<Object>(); 
List<? extends Number> ltemp = null; 
List<?> l2 = ltemp; 

List<T>は、あなたが宣言時に型引数は、クライアントのコンテキスト(例えばタイプ使用)で解決されることを前提としていList<String>またはList<Object>となります。メソッド本体の中で、それについても何も仮定することはできません。

+0

私は最後のコンパイルとは思わない。 –

+0

ありがとうございます。それを修正しました。 – notnoop

1

最初のケースでは、Tは必ずしもStringのスーパークラスである必要はありません。 IntegerのようなTを選択してメソッドを呼び出すと、失敗します。コンパイルされません。しかし、2番目は確実にコンパイルされます。ArrayList<String>Listの何かです。

1

前述のように、StringはTのサブタイプではないため、動作しません。しかし、このコードの動作:

public <T> List<T> meth(List<?> type) 
{ 
    System.out.println(type); // 1 
    return new ArrayList<T>(); // 2 
} 

あなたが望むもののアイデアはもっとあると思います。