最初の行は機能するのに、2 行目は機能しないのはなぜですか?
Collection<Class<? extends Throwable>> exs =
new ArrayList<Class<? extends Throwable>>() {{ add(MyOwnException.class); }};
Collection<Class<? extends Throwable>> exs = Arrays.asList(MyOwnException.class);
エラーの理由は、Javaが間違った型を推測しているためですが、型付きメソッドの呼び出しで型を指定することにより、キャストせずArrays.asList()
にコンパイルさせることができます。
Collection<Class<? extends Throwable>> exs
= Arrays.<Class<? extends Throwable>>asList(Exception.class); // compiles
タイプを指定しない場合、javaはコレクションの要素タイプをに推測しますがClass<Exception>
、これはに割り当てることはできませんCollection<Class<? extends Throwable>>
。
ジェネリックスでは、extendsの場合、B
extendsA
でList<B>
はないことを覚えておいてくださいList<A>
。
ジェネリックは非常に注意が必要です。
この場合、Arrays.asList
はを返しますがList<Class<MyOwnException>>
、これは。と同じではありませんList<Class<? extends Throwable>>
。
List<Class<? extends Throwable>>
このタイプでは、Throwableを拡張するオブジェクトを追加できますがList<Class<MyOwnException>>
、タイプMyOwnExceptionのオブジェクトのみを受け入れるため、これらの動作は異なります。
最初の行が機能するのは、( の)割り当ての右側の要素の型が、 を含む任意の種類のオブジェクトを追加できるためです。最初の行に anまたは aなどを追加することもできます。ArrayList
Class<? extends Throwable>
Class<? extends Throwable>
MyOwnException
Collection
Exception.class
NullPointerException.class
しかし、2 行目はもっと厳密です: a 、 aなどをCollection<Class<? extends Throwable>>
含む可能性のある a があり、 などを許可しないa を配置したい場合。Class<Exception>
Class<NullPointerException>
Collection<Class<MyOwnException>>
Class<Exception>
Arrays.asList(MyOwnException.class)
は type を持つと推測されますが、型パラメーターが異なるためList<Class<MyOwnException>>
と互換性がありません。List<Class<? extends Throwable>>
最初のレベルにワイルドカードを配置すると、機能するはずです。
Collection<? extends Class<? extends Throwable>> exs = Arrays.asList(MyOwnException.class);
2 番目の例が機能する場合、次のようなコードが可能になります。
Collection<Class<? extends Throwable>> exs = Arrays.asList(MyOwnException.class);
exs.add(IOException.class);
問題が見えますか?Arrays.asList()
a を返しList<Class<MyOwnException>>
、それに a を挿入しようとしClass<IOException>
ます。それは明らかに型の不一致です。