SunのコンパイラとEclipse JDTで動きが違う(5)

今回はちょっと難易度高め。
メソッドの型推論にちょっとした穴を見つけたので動作確認してたら動きが異なりました。捕捉変換に関する覚え書き - しげるメモの概要をつかんでないと何言ってるか分からないかもしれません。

class Capture {
    public static void main(String...args) {
        List<?>[] lists = new List<?>[0];
        method(lists); // error in JDT
    }
    static <T> void method(List<T>[] f) {}
}

上記「method(lists)」のlistsの型はList<?>[ ] であり、捕捉変換は適用されません。捕捉変換はパラメータ化型のみに規定されており、その配列型については完全に無視されています。
この型推論の手順を簡単に示すと、

  1. List<?>[ ] << List<T>[ ]
  2. List<?> << List<T>

となりますが、2つ目の時点で型推論規則が存在しなくなってTの推論に失敗している模様です。

なお、上記のコードはSunのコンパイラでは動作します。

ちなみに、listsに捕捉変換が適用されて型変数(仮にX)が生成される場合、次のような推論が行われます。

  1. List<X>[ ] << List<T>[ ]
  2. List<X> << List<T>
  3. X = T
  4. T = X

もしかすると、Sunのコンパイラはパラメータ化型の配列型に対しても捕捉変換を適用しているのかも(たぶん適用しても矛盾はない)。ただし、言語仕様とはちょっと違った動きになっちゃいますね。

Capture conversion on any type other than a parameterized type (§4.5) acts as an identity conversion (§5.1.1). Capture conversions never require a special action at run time and therefore never throw an exception at run time.

5.1.10 Capture Conversion