Genericsとboxingとoverloadと

本日のICPC練習において、すごく気になることがあったので調べてみた。
Collectionクラス全般に言えることだが、例えばLinkedListにある、removeメソッドというメソッドの型定義は、以下のようになっている。

 E remove(int index) 
          リストの指定された位置にある要素を削除します。 
 boolean remove(Object o) 
          リスト内で最初に検出された、指定要素を削除します。 

このメソッドは、オーバーロードされていて、どちらかが静的に決定されて呼び出される。これ自身は別に大したことはないのだけれども、ここにboxingGenericsが絡むとちょっとややこしくなる。

LinkedList list = new LinkedList();
list.add(1);
list.add(2);
list.add(3);
System.out.println(list.remove(1));
System.out.println(list.remove(new Integer(1)));

さて、上記のコードはどのように動くのだろうか。
実際にやってみるとわかるのだが、

1
true

となる。この理由は非常に簡単で、まあ要はこのようなケースにおいてはboxingが行われないのだ。
じゃあ、ということで、例えば以下のコード。

LinkedList list = new LinkedList();
list.add(1);
list.add(2);
list.add(3);
if(list.remove(new Integer(1)) == 1)
    System.out.println("OK");

if(list.remove(1))
    System.out.println("OK");

これはコンパイルエラーになる。本来であれば、boxingが働いて動いて欲しいところだが、残念ながらそうはならない。boxingの動作はかなり怠惰になっていて、さらにこの型チェック機構は決して探索などは行わないらしい。そのほうが分かりやすいと言えばそうなのだけれど・・・