У меня есть перегруженный метод, который принимает в качестве параметров два разных функциональных интерфейса (Runnble
и Supplier
). System.out.println
явно совместим только с Runnable
, потому что это метод void
. Однако компилятор по-прежнему утверждает, что вызов неоднозначен. Как это возможно?
import java.util.function.Supplier;
public class GenericLambdas {
public static void main(String[] args) {
wrap(System.out::println); // Compiler error here
wrap(() -> {}); // No error
wrap(System.out::flush); // No error
}
static <R> void wrap(Supplier<R> function) {}
static void wrap(Runnable function) {}
}
Вывод компилятора:
Error:Error:line (5)java: reference to wrap is ambiguous
both method <R>wrap(java.util.function.Supplier<R>) in GenericLambdas and method wrap(java.lang.Runnable) in GenericLambdas match
Error:Error:line (5)java: incompatible types: cannot infer type-variable(s) R
(argument mismatch; bad return type in method reference
void cannot be converted to R)
Основываясь на второй ошибке (argument mismatch, void cannot be converted to R
), не должен ли компилятор устранить неоднозначность вызова? Тогда это позаботится об обеих ошибках компилятора (поскольку он не будет двусмысленным и не попытается преобразовать void в R).
И почему () -> {}
и System.out::flush
могут разрешить? У них та же подпись, что и у System.out.println
. Допустим, что System.out.println
перегружен версиями, принимающими аргумент, но ни одна из этих перегруженных версий не соответствует ни Supplier
, ни Runnable
, так что я не вижу, как они могут быть здесь уместны.
РЕДАКТИРОВАТЬ:
Кажется, что это действительно компилируется и запускается с Компилятор Eclipse. Какой компилятор правильный или разрешено любое поведение?
System.out::flush
? Однако этот выбирает правильную (Runnable
) перегрузку. 15.10.2015println
неоднозначен, он также не будет жаловаться на тип возвращаемого значения. Если он жалуется на плохой тип возвращаемого значения, это означает, что он уже сопоставилprintln
сSupplier
. 15.10.2015Supplier
, но хочет создать типизированную версию<R> wrap
. Это может быть ошибка. С другой стороны, обе ошибки происходят в одной и той же строке. Измените порядок методовwrap
, и вторая ошибка исчезнет. 15.10.2015