ちょっと古い Oracle Java 8 だと型推論が上限境界付きを認識しないケース

  • 3
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

ローカル環境は 8u45 で Jenkins が 8u11 で、この時、下記コードは Jenkins でのみコンパイルができないってことがあった。型推論が失敗しているっぽい。

問題になったコードを短くしたもの:

Main.java
import static java.util.stream.Collectors.toMap;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<? extends CharSequence> cs = Arrays.asList("a", "b", "cef");
        Map<? extends CharSequence, Integer> m = cs.stream().collect(toMap(
                c -> c,
                c -> c.length()));
        System.out.println(m);
    }
}

それぞれでコンパイルしてみる:

8u45(OKなケース)
$ javac -version
javac 1.8.0_45
$ javac Main.java
$ echo $?
0
8u11(ダメなケース)
$ ./jdk1.8.0_11/bin/javac -version
javac 1.8.0_11
$ ./jdk1.8.0_11/bin/javac Main.java
Main.java:9: エラー: シンボルを見つけられません
                c -> c.length()));
                      ^
  シンボル:   メソッド length()
  場所: タイプObjectの変数 c
Main.java:7: エラー: 不適合な型: 推論型が上限に適合しません
        Map<? extends CharSequence, Integer> m = cs.stream().collect(toMap(
                                                                    ^
    推論: Object
    上限: CharSequence,Object
エラー2個
$ echo $?
1

Collects.toMap 以外のメソッドや、#collect じゃなくて #map#reduce も試してみたんだけどこのような問題は起こらなかった。

ちなみに 8u25 でもエラー文言が違うもののコンパイルできない。u31, u40 は登録しないとダウンロードできないようなので諦め。

型推論が賢くなっているというより、バグなのかな?