bad return type in lambda-Ausdruck
Der folgende code kompiliert werden, Ordnung in IntelliJ und Eclipse, aber der JDK-compiler 1.8.0_25 beschwert. Zuerst der code.
import java.util.function.Predicate;
public abstract class MyStream<E> {
static <T> MyStream<T> create() {
return null;
}
abstract MyStream<E> filter(MyPredicate<? super E> predicate);
public interface MyPredicate<T> extends Predicate<T> {
@Override
boolean test(T t);
}
public void demo() {
MyStream.<Boolean> create().filter(b -> b);
MyStream.<String> create().filter(s -> s != null);
}
}
Die Ausgabe von javac 1.8.0_25 ist:
MyStream.java:18: error: incompatible types: incompatible parameter types in lambda expression
MyStream.<Boolean> create().filter(b -> b);
^
MyStream.java:18: error: incompatible types: bad return type in lambda expression
MyStream.<Boolean> create().filter(b -> b);
^
? super Boolean cannot be converted to boolean
MyStream.java:19: error: bad operand types for binary operator '!='
MyStream.<String> create().filter(s -> s != null);
^
first type: ? super String
second type: <null>
MyStream.java:19: error: incompatible types: incompatible parameter types in lambda expression
MyStream.<String> create().filter(s -> s != null);
^
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
4 errors
Wenn ich ersetzen ? super E
mit einfach E
, JDK erfolgreich kompiliert.
Wenn ich ersetzen filter(MyPredicate
mit filter(Predicate
, JDK erfolgreich kompiliert.
Da es funktioniert mit dem JDK 1.8.0_60, ich vermute, es ist ein compiler-bug.
Alle details auf, was die Ursache dieser, und wenn es behoben worden?
- ja, auch ich glaube, es ist ein compiler-bug. versuchen Sie Problemumgehung
filter((Boolean b)->b))
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn ein lambda-Ausdruck wird in einer Ziel-Typ mit wildcards (wie in den meisten Fällen)
stellt sich die Frage - was ist der Typ des lambda-Ausdrucks; insbesondere die Art der
b
.Natürlich, es gibt viele Entscheidungen, die aufgrund der wildcards; z.B. könnten wir ausdrücklich wählen
Jedoch implizit
b
sollte abgeleitet werden, wieBoolean
. Dies macht Sinn, da der Verbraucher sollte nur gefüttert werden, mitBoolean
sowieso.http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27.3
(Dies ist wahrscheinlich davon ausgegangen, dass die Platzhalterzeichen verwenden Sie ausreichend Varianz-Weise auf das Ziel geben; vielleicht finden wir einige heitere Beispiele, wenn die Annahme nicht zu halten)
<? super E>
umfasstObject
, was nichtBoolean
. ieKönnte ein
ist und Sie nicht mehr zurück können, eine
Object
alsboolean
.Versuchen Sie Ihr lambda:
kompilieren und ausführen, ohne Fehler keine Rolle, die Art des Stroms, aber zurück
true
Elemententrue
Boolean
Werte.Predicate<? super Boolean>
wird der Typ des lambda-Ausdrucks werden solltePredicate<Boolean>
. (jls#12.27.3). Daherb
hat einen statischen Typ vonBoolean