FULL PRODUCT VERSION :
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Darwin eno.local 15.2.0 Darwin Kernel Version 15.2.0: Fri Nov 13 19:56:56 PST 2015; root:xnu-3248.20.55~2/RELEASE_X86_64 x86_64
A DESCRIPTION OF THE PROBLEM :
Type inference fails for a generic method with Function.identity() provided as argument twice. Does not fail when lambda 'x -> x' is substituted for identity() instead.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
$ javac GenericsTest.java
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Expected source file to compile without errors.
ACTUAL -
Compilation fails.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Error:(17, 58) java: method toSortedMap in class com.pexlabs.util.GenericsTest cannot be applied to given types;
required: java.util.function.Function<? super T,? extends K>,java.util.function.Function<? super T,? extends V>
found: java.util.function.Function<java.lang.Object,java.lang.Object>,java.util.function.Function<java.lang.Object,java.lang.Object>
reason: inferred type does not conform to upper bound(s)
inferred: java.lang.Object
upper bound(s): K,java.lang.Comparable<? super K>,java.lang.Object
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package x;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collector;
public class GenericsTest {
public static <T, K extends Comparable<? super K>, V>
Collector<T, ?, Map<K, V>> toSortedMap(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper) {
return null;
}
public static void foo() {
// *** Following statement does not compile ***
Collector<Integer, ?, Map<Integer, Integer>> a = toSortedMap(Function.identity(), Function.identity());
// However this statement compiles just fine
Collector<Integer, ?, Map<Integer, Integer>> b = toSortedMap(i -> i, i -> i);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Use lambda 'x -> x' instead of Function.identity()