Lambda-Ausdruck und Methode überladen Zweifel

OK, Methodenüberladung ist also eine schlechte Sache. Nun, da dies erledigt ist, nehmen wir an, dass ich es tatsächlich tuewollen So überladen Sie eine Methode wie diese:

static void run(Consumer<Integer> consumer) {
    System.out.println("consumer");
}

static void run(Function<Integer, Integer> function) {
    System.out.println("function");
}

In Java 7 konnte ich sie problemlos mit nicht mehrdeutigen anonymen Klassen als Argumente aufrufen:

run(new Consumer<Integer>() {
    public void accept(Integer integer) {}
});

run(new Function<Integer, Integer>() {
    public Integer apply(Integer o) { return 1; }
});

Jetzt in Java 8 möchte ich diese Methoden natürlich mit Lambda-Ausdrücken aufrufen, und das kann ich!

// Consumer
run((Integer i) -> {});

// Function
run((Integer i) -> 1);

Seit dem Compilersollte in der Lage sein zu schließenIntegerWarum gehe ich nicht?Integer dann weg?

// Consumer
run(i -> {});

// Function
run(i -> 1);

Aber das kompiliert nicht. Dem Compiler (javac, jdk1.8.0_05) gefällt das nicht:

Test.java:63: error: reference to run is ambiguous
        run(i -> {});
        ^
  both method run(Consumer<Integer>) in Test and 
       method run(Function<Integer,Integer>) in Test match

Für mich ist das intuitiv nicht sinnvoll. Zwischen einem Lambda-Ausdruck, der einen Rückgabewert liefert ("value-compatible") und einem Lambda-Ausdruck, der liefert, besteht absolut keine Mehrdeutigkeitvoid ("leerraumkompatibel"), wie in derJLS §15.27.

Aber natürlich ist das JLS tiefgreifend und komplex. Wir haben 20 Jahre Erfahrung in der Rückwärtskompatibilität und es gibt neue Dinge wie:

Bestimmte Argumentausdrücke, die enthaltenimplizit typisierte Lambda-Ausdrücke (§15.27.1) oder ungenaue Methodenreferenzen (§15.13.1) werden von den Anwendbarkeitstests ignoriert, da ihre Bedeutung erst nach Auswahl eines Zieltyps bestimmt werden kann.

von JLS §15.12.2

Die obige Einschränkung hängt wahrscheinlich damit zusammen, dassJEP 101 wurde nicht vollständig implementiert, wie zu sehen istHier undHier.

Frage:

Wer kann mir genau sagen, welche Teile des JLS diese Mehrdeutigkeit beim Kompilieren spezifizieren (oder handelt es sich um einen Compiler-Fehler)?

Bonus: Warum wurden die Dinge so entschieden?

Aktualisieren:

Mit jdk1.8.0_40 wird das Obige kompiliert und funktioniert einwandfrei

Antworten auf die Frage(3)

Ihre Antwort auf die Frage