このコードがコンパイルされる理由
final ArrayList<?> dp1 = new ArrayList<String>();
しかし、これはそうではありません
final ArrayList<ArrayList<?>> dp2 = new ArrayList<ArrayList<String>>();
理解するのは非常に複雑ですが、要約すると、最初のコードはString
拡張されます?
が、2 番目のコードはコンパイルされArrayList<String>
ません。2 番目の例をコンパイルする場合は、次のように変更する必要があります。ArrayList<?>
final ArrayList<? extends ArrayList<?>> dp2 = new ArrayList<ArrayList<String>>();
の
final ArrayList<?> dp1 = new ArrayList<String>();
type 引数?
は、 のスーパーセット (スーパータイプではない) であるワイルドカードですString
。で、ArrayList<?>
のスーパータイプですArrayList<String>
。
しかし、
final ArrayList<ArrayList<?>> dp2 = new ArrayList<ArrayList<String>>();
型引数ArrayList<?>
(?
未知の型を表すだけで、 とは何の関係もないパラメータ化された型String
) はワイルドカードではありません。ワイルドカードは であり? extends ArrayList<?>
、ArrayList<?>
実際には のスーパータイプですArrayList<String>
。
パラメータ化された型のスーパー/サブ セット/型に関する規則については、こちらを参照してください。