2012-01-05 28 views

答えて

1

具体的な型宣言では、インタフェースを汎用パラメータとして使用しているので、これが起こります。それが将来的に使用される方法を考える:

List someList = new ArrayList<Set<?>>();  
Set<?> someSet = new HashSet<Integer>(); 
someList.add(someSet); 

を最初の行で - あなたは(あらゆるタイプの)「いくつかのセット」を開催しますArrayListタイプのリストを、定義しています。次に、2行目で具体的なタイプのセットを宣言し定義していますHashSetSet<?>にキャストされているので、以前に作成したリストに追加することに問題はありません。

2

ArrayListを作成するときは、その汎用パラメータに明示的な型を指定する必要があります。 ?または? extends Numberはタイプではありません。 Set<?>は型(つまり、汎用型を気にしないSet)です。

0

が不明なため?はどのタイプにも翻訳できません。

new ArrayList<?>(); 

(これはコンパイルできると仮定します)。

List<?> list = new ArrayList<?>(); 
list.add(? e); //Java sees this as WTF??? 

この?が不明であるので、Javaはlist.add(null e);にこれを変換し、これがerrornousです。

+0

それが本当であれば、 '一覧リスト=新しいArrayListを()'も違法であってもよいが、そうでないはずです。 – yshavit

+0

@yshavit、私は 'ArrayList ()'を指定せず、 'ArrayList ()'を指定しましたが、あなたが指定したのは別のケースです。 –

+0

私は理解しますが、 'List list = new ArrayList ()'を 'List list = new ArrayList ()'に置き換えると、2行目は完全に変更されません。だから、 'new ArrayList ()'がなぜ許可されないのか説明していません。 – yshavit

1

答えはので、ここであなたがを行うために必要となるものだ、すでに与えられている代わりに

ArrayList example1 = new ArrayList(); // any object will do. 
ArrayList<Object> example2 = new ArrayList<Object>(); // since everything inherits from Object anyway... 
:あなたがリストに含まれているものの種類を気にしない場合は何の

ファースト

そして、あなたは、任意のNumberオブジェクトを追加したい場合はどのような:

ArrayList<Number> example3 = new ArrayList<Number>(); // any Number may be added 

最後に、以前の回答glosをあなたの最後の例の意味を超えています。 1はあなたが見つけることを期待するArrayListを構築することを意味し

ArrayList<Set<?>> example4 = new ArrayList<Set<?>>(); 

は/任意の型のオブジェクトを含むことがSet秒を置きます。私。あなたはSetの内容を気にしませんが、ArrayListにあなたが追加するのはSetです。

その結果、すべての操作の範囲内が新しく宣言した上で実行/ Set<?>の一部が自由にSetに変換することができArrayListを作成しました。その結果プログラムは、同等の意味を持つことになります。

0

new ArrayList<?>()はそれほど有用ではありません。

  • ? extends Fooは、あなたが(nullを除く)には何も入れていないことを意味していますが、Fooなどからオブジェクトを取得することができます
  • ? super FooはあなたがFoo Sを置くことができることを意味し、:それはワイルドカードが何を意味するかを考えると便利ですしかし、あなたは
  • ?が交差点である(Objectなどを除く)のオブジェクトを取得することはできません:あなたは(nullを除く)には何も置くことができない、あなたは(Objectなどを除く)のオブジェクトを取得することはできません

,List<? super Foo>またはList<?>にキャストすることができますが、3つのうちどれも安全にキャストできないことに注意してください。List<Foo>

だから、new ArrayList<?>()を作成したとします。どのような参照を割り当てることができますか? List<?>のみつまり、(null以外の)参照を入れることができなくなり、Object以外の参照を出すことができなくなります。言い換えれば、このジェネリックは、ジェネリックスが置き換えられることになっていた生のタイプよりも少し役に立たない。

List<?>またはList<? extends Foo>が表示された場合、誰かがワイルドカードを使用しない型として作成した後、ワイルドカード型にキャストする可能性が非常に高いです。例えば:numbersList<? extends Number>として入力されていた場合、それは便利なかったであろうように、この例では

List<? extends Number> getSomeNumbers() { 
    List<Number> numbers = new ArrayList<Number>(); 
    numbers.add(1); 
    numbers.add(2L); 
    numbers.add(3.14); 
    return numbers; // implicit casting to List<? extends Number> 
} 

addラインのどれも、コンパイルされなかっただろう。オブジェクトをnew ArrayList<? extends Number>()というように構築した場合は、無用なワイルドカード形式で参照するしかありません。

同様に、new ArrayList<? super Number>()を作成した場合、加算は機能しますが、誰もがObject以外の値を取得できないことを保証します。 new ArrayList<Object>()を作成(参照)するだけで同じことができました。

だから、なぜnew ArrayList<Set<?>>()が許可されていますか? ですので便利です。リストに要素を追加するだけでなく、要素を取得することもできます。各セットを作成するときに、ワイルドカードを使用しないでワイルドカードを作成して追加してから、それをキャストしてリストに追加します。

List<Set<?>> getSomeSets() { 
    List<Set<?>> list = new ArrayList<Set<?>>(); 
    Set<Number> set = new HashSet<Number>(); 
    set.add(1); 
    set.add(2L); 
    set.add(3.14); 
    Set<?> wildcardSet = set; // allowed, though not actually needed 
    list.add(wildcardSet); 
    list.add(set); // don't need to go through intermediate wildcardSet 
    return list; 
} 
関連する問題