2017-07-02 9 views
3
public static void reverse(List<?> list) 
{ 
List<Object> tmp = new ArrayList<Object>(list); 
for (int i = 0; i < list.size(); i++) 
{ 

list.set(i, tmp.get(list.size()-i-1)); // compile-time error , why ? 

} 

} 

私はジェネリックを学んでいます。 私はこれを知っています:ワイルドカードを使用すると?適切なタイプに置き換えられます。 reverse()メソッドが?すべての型がObjectのサブタイプであるため、エラーは発生しません。 私は明確な説明を求めています。助けてください 。わかりにくいワイルドカード

+1

'一覧は' _unbounded_ワイルドカード。つまり、リストには 'null'しか挿入できません。 –

+0

https://docs.oracle.com/javase/tutorial/java/generics/unboundedWildcards.html –

+2

あなたは「?」を誤解しています。それは置き換えられません。 *未知数*を識別します。 – Andreas

答えて

1

あなたはList<?> list引数としてごreverse方法に任意のList<SomeType>を渡すことができ、コンパイラは、あなたがそのListSomeTypeの要素を追加できるようにする必要があります。コンパイラは、メソッドに渡された実際のList<?> listがサポートしている要素の型を知らないので、

は例えば、それは、

。したがって list.setが動作しないことができる... List<String>List<Ineger>、などである可能性があります。 List<Object> tmpの要素が同じ listに由来することはわかりません(したがって、安全に追加できます)。

public static <T> void reverse(List<T> list) 
{ 
    List<T> tmp = new ArrayList<> (list); 
    for (int i = 0; i < list.size(); i++) { 
     list.set(i, tmp.get(list.size()-i-1)); 
    } 
} 

今コンパイラがlisttmpの両方が同じ型の要素が含まれていることを知っている:

あなたの方法を記述するための正しい方法は、ジェネリック型パラメータを定義することです。

+0

Box の違いは何ですか?box = new Box <>( "hello");ボックスボックス=新しいボックス( "hello"); ここで、ボックスはクラスボックスです。 {T t; ボックス(T t){this.t = t; }} – steve

+0

@steve私は前者が 'Box 'を作成すると考えています( 'new Box <>'のジェネリックパラメータの型は 'box'変数の型から推測できないので)。 'Box '。 – Eran

0

Generics work in this way。ここで

public static void reverse(List<?> list) 

我々はそれにオブジェクトを追加することはできません、ためlistの要素型が立っているのか分からないと。ここで

List<Object> tmp = new ArrayList<Object>(list); 
    ... 
list.set(i, tmp.get(list.size()-i-1)); // compile-time error , why ? 

あなたは絶対的に異なるタイプの要素を含むことができListObject秒を追加します。あなたのケースで
は、あなたが書いている場合ではありません。

List<Object> tmp = new ArrayList<Object>(list); 

しかし、コンパイラは、コードのロジックを理解しようとすることで、例外を作成しません。
それ以外の場合は、コード全体を検査する必要があり、コンパイラのエラーメッセージが実際に複雑になる可能性があるからです。
たとえば、コードで一度にadd tmp.set(0, "aa");とします。

0

List<?>が知られていないタイプのリストである、我々はこのリスト内のどのタイプを知らない、ジェネリックは削除実行時の型キャストの例外のために導入され、安全性を与えました。あなたはそれを壊すので、未定義のcontainsを持つコレクションに型を追加することはできません。例これは、許可される場合:

List<Dog> dogs = new ArrayList<>(Arrays.asList(new Dog("dog"))); 

    public doSomething(List<?> notKnownType) { 
     notKnownType.add(new Cat("cat")); 
// if this ok or not? <?> is not known type, all types have Object as parent let's add Cat 
    } 

    for (Dog dog : dogs) { 
     System.out.println(dog); //ClassCastException 
    } 

ClassCastExceptin私たちは犬に猫を追加し、猫にすべての犬を投げ、ランタイムジェネリックに とすべてのコレクションを存在しないとなどためのオブジェクトが含まれています。 は、この行は、コンパイル後にそのようなことになります。これは、あなたが何かを知られないようにするタイプのコレクションを追加し、タイムエラーをコンパイル取得することができないことはできませ用

for (Object dog : dogs) { 
    System.out.println((Dog) dog); //ClassCastExceptin 
} 

ここlist.set(i, tmp.get(list.size()-i-1)); // compile-time error , why ?

関連する問題