Java の総称型は便利だけどちょっと残念

Java の総称型はかなり便利で、いやそれまでが不便だったんだけど、それに気がつかなかったということかも知れない。

たとえばこういう宣言を見ると、ちょっと苦痛に感じる。

List list = new ArrayList();
  • このリストには何が入ってんだよ?
  • 参照するときキャストしなきゃなんないじゃん


これが、こうなっていると安心する。

List<? extends Foo> list = new ArrayList<? extends Foo>();
  • なるほどね、Foo のサブクラスが入ってるわけか
  • 少なくとも Foo として抽象的に扱えばよいということね
  • スペシャルケースがあるかも知れないから List ではないわけね


ただ、ちょっと残念なのは以下のように省略できないこと。

List<? extends Foo> list = new ArrayList();

いや、正確には省略できるんだけど、警告が出てしまう。Java 7 だと以下のように書けるけど僕が仕事で Java 7 を主戦場とするのは、まだまだ先の話だなぁ。

List<? extends Foo> list = new ArrayList<>();


ちなみによくわかってないのは、以下の違い。

List<?> list1;
List<Object> list2;
list1 = list2; // コンパイルエラー
list2 = list1; // 問題なし

? と Object は何が違うのか。