FULL PRODUCT VERSION :
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.10240]
A DESCRIPTION OF THE PROBLEM :
Consider an overloaded method that takes two different functional interfaces as parameters (`Runnble` and `Supplier`). `System.out.println` is clearly only compatible with `Runnable`, because it is a `void` method. javac agrees, reporting an error that explicitly notes that the return type of `Supplier` cannot be converted to void. Yet javac still claims in a separate error that the call is ambiguous and matches both `Runnable` and `Supplier`.
Note that both lambda `() -> {}` and method reference `System.out::flush` are able to resolve. The difference appears to be that `System.out.println` is overloaded with versions that take an argument. As none of those overloaded versions match either `Supplier` or `Runnable`, it is unclear how they would be relevant here.
Another note is that this does resolve correctly and compile with the Eclipse compiler.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
>javac.exe -cp . GenericLambdas.java
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Ability to successfully compile and run. javac should select this overloaded version of wrap:
static void wrap(Runnable function){}
ACTUAL -
javac is unable to compile the class
ERROR MESSAGES/STACK TRACES THAT OCCUR :
GenericLambdas.java:5: error: reference to wrap is ambiguous
wrap(System.out::println);
^
both method <R>wrap(Supplier<R>) in GenericLambdas and method wrap(Runnable) in GenericLambdas match
where R is a type-variable:
R extends Object declared in method <R>wrap(Supplier<R>)
GenericLambdas.java:5: error: incompatible types: cannot infer type-variable(s) R
wrap(System.out::println);
^
(argument mismatch; bad return type in method reference
void cannot be converted to R)
where R is a type-variable:
R extends Object declared in method <R>wrap(Supplier<R>)
2 errors
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.function.Supplier;
public class GenericLambdas {
public static void main(String[] args) {
wrap(System.out::println); // Compiler error here
wrap(() -> {}); // No error
}
static <R> void wrap(Supplier<R> function) {}
static void wrap(Runnable function) {}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Explicitly casting the method reference to `Runnable`:
wrap((Runnable) System.out::println);
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.10240]
A DESCRIPTION OF THE PROBLEM :
Consider an overloaded method that takes two different functional interfaces as parameters (`Runnble` and `Supplier`). `System.out.println` is clearly only compatible with `Runnable`, because it is a `void` method. javac agrees, reporting an error that explicitly notes that the return type of `Supplier` cannot be converted to void. Yet javac still claims in a separate error that the call is ambiguous and matches both `Runnable` and `Supplier`.
Note that both lambda `() -> {}` and method reference `System.out::flush` are able to resolve. The difference appears to be that `System.out.println` is overloaded with versions that take an argument. As none of those overloaded versions match either `Supplier` or `Runnable`, it is unclear how they would be relevant here.
Another note is that this does resolve correctly and compile with the Eclipse compiler.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
>javac.exe -cp . GenericLambdas.java
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Ability to successfully compile and run. javac should select this overloaded version of wrap:
static void wrap(Runnable function){}
ACTUAL -
javac is unable to compile the class
ERROR MESSAGES/STACK TRACES THAT OCCUR :
GenericLambdas.java:5: error: reference to wrap is ambiguous
wrap(System.out::println);
^
both method <R>wrap(Supplier<R>) in GenericLambdas and method wrap(Runnable) in GenericLambdas match
where R is a type-variable:
R extends Object declared in method <R>wrap(Supplier<R>)
GenericLambdas.java:5: error: incompatible types: cannot infer type-variable(s) R
wrap(System.out::println);
^
(argument mismatch; bad return type in method reference
void cannot be converted to R)
where R is a type-variable:
R extends Object declared in method <R>wrap(Supplier<R>)
2 errors
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.function.Supplier;
public class GenericLambdas {
public static void main(String[] args) {
wrap(System.out::println); // Compiler error here
wrap(() -> {}); // No error
}
static <R> void wrap(Supplier<R> function) {}
static void wrap(Runnable function) {}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Explicitly casting the method reference to `Runnable`:
wrap((Runnable) System.out::println);