ADDITIONAL SYSTEM INFORMATION :
openjdk full version "12-ea+19"
A DESCRIPTION OF THE PROBLEM :
In the reproducer, I have a class with 2 overloaded methods named "pipe", one taking a Function, the other a Consumer. javac says that both methods are applicable when passing "System.out::println" as an argument. However, I don't see how "System.out::println" can be considered a Function. In the given class I also try to assign "System.out::println" to a variable of type Function<String, Void> (which is the closest applicable type I can imagine), but this gives an error as expected. So I don't see why there's an ambiguity, and if I understand the specification [1] correctly, there actually isn't.
[1] https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.12.2.1
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the given class
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The class gives 1 error:
Wrapper.java:18: error: incompatible types: bad return type in method reference
Function<String, Void> f = System.out::println;
^
void cannot be converted to Void
ACTUAL -
The class gives 3 errors. Besides the expected error, it also gives the following 2:
Wrapper.java:15: error: reference to pipe is ambiguous
new Wrapper<>("hello world").pipe(System.out::println);
^
both method <R>pipe(Function<? super T,? extends R>) in Wrapper and method pipe(Consumer<? super T>) in Wrapper match
where R,T are type-variables:
R extends Object declared in method <R>pipe(Function<? super T,? extends R>)
T extends Object declared in class Wrapper
Wrapper.java:15: error: incompatible types: cannot infer type-variable(s) R
new Wrapper<>("hello world").pipe(System.out::println);
^
(argument mismatch; bad return type in method reference
void cannot be converted to R)
where R,T are type-variables:
R extends Object declared in method <R>pipe(Function<? super T,? extends R>)
T extends Object declared in class Wrapper
---------- BEGIN SOURCE ----------
import java.util.function.Consumer;
import java.util.function.Function;
public class Wrapper<T> {
private final T t;
public Wrapper(T t) { this.t = t; }
public <R> R pipe(Function<? super T, ? extends R> f) { return f.apply(t); }
public void pipe(Consumer<? super T> c) { c.accept(t); }
public static void main(String... args) {
new Wrapper<>("hello world").pipe(System.out::println);
Consumer<String> c = System.out::println;
Function<String, Void> f = System.out::println;
}
}
---------- END SOURCE ----------
openjdk full version "12-ea+19"
A DESCRIPTION OF THE PROBLEM :
In the reproducer, I have a class with 2 overloaded methods named "pipe", one taking a Function, the other a Consumer. javac says that both methods are applicable when passing "System.out::println" as an argument. However, I don't see how "System.out::println" can be considered a Function. In the given class I also try to assign "System.out::println" to a variable of type Function<String, Void> (which is the closest applicable type I can imagine), but this gives an error as expected. So I don't see why there's an ambiguity, and if I understand the specification [1] correctly, there actually isn't.
[1] https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.12.2.1
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the given class
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The class gives 1 error:
Wrapper.java:18: error: incompatible types: bad return type in method reference
Function<String, Void> f = System.out::println;
^
void cannot be converted to Void
ACTUAL -
The class gives 3 errors. Besides the expected error, it also gives the following 2:
Wrapper.java:15: error: reference to pipe is ambiguous
new Wrapper<>("hello world").pipe(System.out::println);
^
both method <R>pipe(Function<? super T,? extends R>) in Wrapper and method pipe(Consumer<? super T>) in Wrapper match
where R,T are type-variables:
R extends Object declared in method <R>pipe(Function<? super T,? extends R>)
T extends Object declared in class Wrapper
Wrapper.java:15: error: incompatible types: cannot infer type-variable(s) R
new Wrapper<>("hello world").pipe(System.out::println);
^
(argument mismatch; bad return type in method reference
void cannot be converted to R)
where R,T are type-variables:
R extends Object declared in method <R>pipe(Function<? super T,? extends R>)
T extends Object declared in class Wrapper
---------- BEGIN SOURCE ----------
import java.util.function.Consumer;
import java.util.function.Function;
public class Wrapper<T> {
private final T t;
public Wrapper(T t) { this.t = t; }
public <R> R pipe(Function<? super T, ? extends R> f) { return f.apply(t); }
public void pipe(Consumer<? super T> c) { c.accept(t); }
public static void main(String... args) {
new Wrapper<>("hello world").pipe(System.out::println);
Consumer<String> c = System.out::println;
Function<String, Void> f = System.out::println;
}
}
---------- END SOURCE ----------