2013-08-12 9 views
18

Javaのジェネリック型拡張:Java汎用タイプ:List <?数を拡張>とList <Tは数>

(1) List <? extends Number> 
(2) List <T extends Number> 

との差が、私の理解あたりとして何

(1)List <? extends Number>は "不明" は、データの 読み取り専用のリストですスーパークラス "番号"と入力します。要素を読み取ることはできますが、追加することはできません。

(2)List <T extends Number> スーパークラス "番号"のデータ型のリスト。私は、エラーを取得sumOfList2に整数(または偶数オブジェクト)を追加しようとしていたとき、私たちは

class TestGen{ 

     public static void main(String[] args) { 

     double result = 0.0; 

     List<Integer> intList = new ArrayList<Integer>(); 
     intList.add(10); 
     intList.add(20); 
     intList.add(30); 

     result = TestGen.sumOfList1(intList); 
     System.out.println("Result=" + result); 

     result = TestGen.sumOfList2(intList); 
     System.out.println("Result=" + result); 
    } 

    public static double sumOfList1(List<? extends Number> list) { 
     double s = 0.0; 
     for (Number n : list) 
      s += n.doubleValue(); 
     return s; 
    } 


    public static <T extends Number> double sumOfList2(List<T> list) { 

     double s = 0.0; 

     // -- --------------------------------------------------------- 
     // getting error while trying to add new element 
     // list<T> is not applicable for argument(Integer) : Why ? 
     list.add(new Integer(40));      

     for (Number n : list)    
      s += n.doubleValue(); 

     return s; 
    } 
} 

次のコード例を参照してくださいリスト

要素を読み、追加してくださいすることができます。何が間違っているのか説明してください。

答えて

18

基本的な違いがあるT
たとえば :list.add((T) new Integer(40));
あなたが? extends Numberを使用している場合、あなたは型を参照することはできませんが、あなたはまだ孤立して((List<Integer>)list).add((int) s);

+0

なぜそれが落とされたのか、何かのヒント?どうかしましたか? – BVMR

+0

誰が投票したのか分かりません。この解決策は機能します。キャスティングが必要な理由を明かすことができますか? list.add((T)new Integer(40)); サブクラスのみのオブジェクトを追加している間(IntegerはNumberのサブクラスです) –

+0

'T'にキャストすると' type safety'という警告が出ます。 – GGrec

1

sumOfList2において、TNumberの特定のサブクラスであるが、それらのどれでもよい。たとえば、TBigDecimalで、にはIntegerを追加できません。あなたがリストに番号のいずれかのタイプを追加できるようにしたい場合は

は、それがなければならないList<Number>

あなたは、あなたがタイプを参照することができ T extends Numberを使用する場合
public static double sumOfList2(List<Number> list) {...} 
10

言うことができるよう、メートルありませんuchの違い。しかし、単一の文脈におけるList<? extends Number>の2つのインスタンスは完全に無関係であり、単一の文脈におけるList<T extends Number>の2つのインスタンスは同じTおよび同じインタフェースを参照する。 ntoに添加し、そしてfromtoのメンバー型が完全に異なることができるので、また失敗することができないため

public void addAll(List<? extends Number> to, List<? extends Number> from) { 
    for (Number n: from) { 
     to.add(n); 
    } 
} 

この方法は失敗します。

public <T> void addAll(List<T extends Number> to, List<T extends Number> from) { 
    for (T n: from) { 
     to.add(n); 
    } 
} 

このメソッドは正常にコンパイルされます。それは必要ではありません。 Collectionsはより良いバージョンですが、エラーなく実行されます。

+1

にキャストする必要があります。実際に 'addAll(List to、... ' void addAll(List to、... –

-1

最初のケースは非常に単純で、T extends Numberから知られています。そのTは、Numberクラスまたはその子タイプのObjectです。 これは、我々は数の型としてTを使用する方法を持っている場合、我々は

<T extends Number> void myMethod (List <T> num){ 
    num.add(1); // 1 is an Integer 
    num.add(2.3) // 2.3 is a Double 
} 

すなわちしかし、この*ワイルド文字「に応じて私たちの方法を操作することができることを意味?'*私たちも、それは数を拡張する場合かかわらず、参照されようとしているが、それは任意の種類のオブジェクトでき​​るオブジェクトの種類がわからない場合

void myMethod(List <? extends Number> num){ 
    // num.add(1); // not a valid statement, as we dont know if '1' is of the type '?' 
    // num.add(2.3) // not a valid statement, as we dont know if '2.3' is of the type '?' 
} 

だから、このようにダウン書くことができる唯一の値ステートメントはnullです。任意のタイプのObjectはnullでもかまいません。

void myMethod(List <? extends Number> num){ 
     num.add(null) 
    } 

このようなメソッドは読み取り専用メソッドです。

+0

)最初のサンプルを実際にコンパイルすることはできません。 – yuxh

関連する問題