Java 8 Consumer / Function Lambda Ambiguity
У меня есть перегруженный метод, который принимает Consumer и объект Function соответственно и возвращает универсальный тип, который соответствует соответствующему Consumer / Function. Я думал, что это будет хорошо, но когда я пытаюсь вызвать любой метод с лямбда-выражением, я получаю ошибку, указывающую, что ссылка на метод неоднозначна.
Основываясь на моем чтенииJLS §15.12.2.1. Определите потенциально применимые методы: похоже, что компилятор должен знать, что моя лямбда с блоком void соответствует методу Consumer, а моя лямбда с типом возврата соответствует методу Function.
Я собрал следующий пример кода, который не компилируется:
import java.util.function.Consumer;
import java.util.function.Function;
public class AmbiguityBug {
public static void main(String[] args) {
doStuff(getPattern(x -> System.out.println(x)));
doStuff(getPattern(x -> String.valueOf(x)));
}
static Pattern<String, String> getPattern(Function<String, String> function) {
return new Pattern<>(function);
}
static ConsumablePattern<String> getPattern(Consumer<String> consumer) {
return new ConsumablePattern<>(consumer);
}
static void doStuff(Pattern<String, String> pattern) {
String result = pattern.apply("Hello World");
System.out.println(result);
}
static void doStuff(ConsumablePattern<String> consumablePattern) {
consumablePattern.consume("Hello World");
}
public static class Pattern<T, R> {
private final Function<T, R> function;
public Pattern(Function<T, R> function) {
this.function = function;
}
public R apply(T value) {
return function.apply(value);
}
}
public static class ConsumablePattern<T> {
private final Consumer<T> consumer;
public ConsumablePattern(Consumer<T> consumer) {
this.consumer = consumer;
}
public void consume(T value) {
consumer.accept(value);
}
}
}
Я также нашеланалогичный сообщение stackoverflow, которое оказалось ошибкой компилятора. Мой случай очень похож, хотя и немного сложнее. Для меня это все еще выглядит как ошибка, но я хотел убедиться, что я не неправильно понимаю спецификацию языка для лямбд. Я использую Java 8u45, которая должна иметь все последние исправления.
Если я изменю свои вызовы методов, чтобы они были обернуты в блок, кажется, что все компилируется, но это добавляет дополнительную многословность, и многие автоформаторы переформатируют его в несколько строк.
doStuff(getPattern(x -> { System.out.println(x); }));
doStuff(getPattern(x -> { return String.valueOf(x); }));