Edited at

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

More than 3 years have passed since last update.

ローカル環境は 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 は登録しないとダウンロードできないようなので諦め。

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