2016-08-16 6 views
-1

ジェネリック型を使用して問題を解決できる場合は、Javaが無制限のワイルドカードを提供した理由例無制限のワイルドカードとJavaの汎用タイプの違いは何ですか?

class UnBoundedUsage { 

    //Method 1 
    public static void unboundedMethod(List<?> list) { 
     for(Object obj : list) { 
      System.out.println(obj); 
     } 
    } 

    //Method 2 
    public static <T> void methodWithType(List<T> list) { 
     for(T obj : list) { 
      System.out.println(obj); 
     } 
    } 
} 

については は、誰もが方法2は、私たちの要求を解決することができるなら、私は理解する助けてくださいすることができ、その後、なぜ我々は方法1を持っている必要があります。 無限のワイルドカードを使用して解決できる問題であり、汎用メソッドタイプ(たとえば方法2)を使用して解決できない問題を意味しますか?

+2

メソッド2の 'list'に要素を追加できます。方法1ではできません。 –

+0

ありがとう@AndyTurnerしかし、要素の追加が唯一の問題ならば、コードスニペット以下に変更することができます public static void methodWithType(List list){ for(Object obj:list) { System.out.println(obj); } } – MishraJi

+0

これは唯一の問題ではありません。これはコンパイラが安全を保証できるように、型変数が十分な情報を提供するという問題の単なる例です。 –

答えて

1

違いは、方法1では、リスト要素の種類については何も知らないことです。リスト要素で行うことができるのは、Objectのように扱います。

Object obj = list.get(0); 

リストのジェネリック型がObjectであるという保証はありませんので、あなたも、バックリストにこの要素を追加することはできません。

List<Integer> list = new ArrayList<>(Arrays.asList(1)); 
method1(list); 

void method1(List<?> list) { 
    Object obj = list.get(0); 
    list.add(obj); // Compiler error! Can't add an Object to the List. 
} 

をしかし、あなたはタイプを使用する場合は、これを行うことができますコンパイラはリストから出てくる要素に関する型情報を持っているので、そして戻って要素を追加しても安全であることを知るためにこれを使用することができます:

List<Integer> list = new ArrayList<>(Arrays.asList(1)); 
method2(list); 

<T> void method2(List<T> list) { 
    T obj = list.get(0); 
    list.add(obj); // OK! 

    // But, if you discard the type information... 
    Object obj1 = list.get(0); 
    list.add(obj1); // Still a compiler error. 
} 

Tの消去タイプはまだObjectです。コンパイラがTへの参照を参照すると、リストの要素の境界と互換性があることがわかります。

関連する問題