I have two functions similar to these ones:
public static <In extends Number, Out extends Number> Out test(In in, Function<In, Out> f) {
Out x = f.apply(in);
return test(in, x);
}
public static <In extends Number, Out extends Number> Out test(In in, Out out) {
return out;
}
To me it is obvious that they cannot(!) clash and that calls cannot be ambiguous. However, with the most recent version of Java 8, the following call fails:
Test.test(2, Integer::new);
with Error:(17, 16) java: reference to test is ambiguous
both method <In,Out>test(In,java.util.function.Function<In,Out>) in org.test and method <In,Out>test(In,Out) in org.test match
while
Test.test(2, new Function<Integer, Number>() {
@Override
public Number apply(Integer integer) {
return 10;
}
});
and
Test.test(2, (Function<Integer, Number>) integer -> 10);
work.
Is this a bug in the compiler (or should this fail?)
More information about my setup below
Java version:
Desktop $ java -version
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
Error:
Test.java:5: error: reference to test is ambiguous
Test.test(2, Integer::new);
^
both method <In#1,Out#1>test(In#1,Function<In#1,Out#1>) in Test and method <In#2,Out#2>test(In#2,Out#2) in Test match
where In#1,Out#1,In#2,Out#2 are type-variables:
In#1 extends Number declared in method <In#1,Out#1>test(In#1,Function<In#1,Out#1>)
Out#1 extends Number declared in method <In#1,Out#1>test(In#1,Function<In#1,Out#1>)
In#2 extends Number declared in method <In#2,Out#2>test(In#2,Out#2)
Out#2 extends Number declared in method <In#2,Out#2>test(In#2,Out#2)
Test program:
import java.util.function.Function;
public class Test {
public static void main(String[] args) {
Test.test(2, Integer::new);
}
public static <In extends Number, Out extends Number> Out test(In in, Function<In, Out> f) {
Out x = f.apply(in);
return test(in, x);
}
public static <In extends Number, Out extends Number> Out test(In in, Out out) {
return out;
}
}
Since the issue is confirmed by others, I've reported it as a bug to Oracle.
Test.test(2, Integer::new);
should not fail. Indeed, it does not fail for me. Running:
C:\Users\David>java -version
java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)
C:\Users\David>javac -version
javac 1.8.0_20
From what I can tell, this is the most recent. What platform are you working on?
As it turns out, this is a bug on OSX (and not on Windows). If someone has a *NIX box, they should also test OP's code.
I have the same problem, but I tried this:
Test.test(2, Function.identity() ); // OK
Test.test(2, val -> 2L ); // FAIL
Test.test(2, Function.<Integer>identity().andThen(a -> a * 2)); // OK
Test.<Integer,Long>test(2, val -> 2L ); // OK
Test.test(2, (final Integer a) -> a* 2 ); // FAIL
While this fails in Javac (Debian Wheezy + jdk1.8.0_20x64), it works fine in Eclipse.
On a side note, I guess it's one of those type inference problems. You should probably fill a bug report.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With