Java 8 Consumer / Function Lambda Ambiguity
Ich habe eine überladene Methode, die ein Consumer- bzw. ein Function-Objekt verwendet und einen generischen Typ zurückgibt, der mit dem entsprechenden Consumer / Function übereinstimmt. Ich dachte, das wäre in Ordnung, aber wenn ich versuche, eine der beiden Methoden mit einem Lambda-Ausdruck aufzurufen, erhalte ich eine Fehlermeldung, die darauf hinweist, dass der Verweis auf die Methode nicht eindeutig ist.
Basiert auf meinem Lesen vonJLS §15.12.2.1. Mögliche anwendbare Methoden identifizieren: Es scheint, als sollte der Compiler wissen, dass mein Lambda mit einem void-Block mit der Consumer-Methode und mein Lambda mit einem return-Typ mit der Function-Methode übereinstimmen.
Ich habe den folgenden Beispielcode zusammengestellt, der nicht kompiliert werden kann:
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);
}
}
}
Ich habe auch ein @ gefundähnlic stackoverflow Beitrag, der sich als Compiler-Fehler herausstellte. Mein Fall ist sehr ähnlich, wenn auch etwas komplizierter. Für mich sieht das immer noch nach einem Fehler aus, aber ich wollte sicherstellen, dass ich die Sprachspezifikation für Lambdas nicht missverstehe. Ich verwende Java 8u45, das die neuesten Korrekturen haben sollte.
Wenn ich meine Methodenaufrufe so ändere, dass sie in einen Block eingeschlossen werden, scheint alles zu kompilieren, aber dies fügt zusätzliche Ausführlichkeit hinzu und viele Auto-Formatierer formatieren es in mehrere Zeilen um.
doStuff(getPattern(x -> { System.out.println(x); }));
doStuff(getPattern(x -> { return String.valueOf(x); }));