Ich versuche herauszufinden, warum dieser Code nicht auf JDK 1.8.0_45
kompiliert:
Das Hinzufügen eines scheinbar unnötigen Cast korrigiert es:
%Vor%Hier ist der Fehler vom Compiler:
%Vor% Aus irgendeinem Grund wird der Rückgabetyp von lookup()
nicht korrekt auf etwas zurückgeführt, das Example
erweitert.
Als Peter Lawrey darauf hingewiesen , ? extends Example<?>
ist nicht kompatibel mit E extends Example<E>
. Selbst wenn die Signatur repariert wird, funktioniert das hier nicht.
Der Grund ist eine bekannte Einschränkung der Typinferenz, da sie nicht durch verkettete Methodenaufrufe zurückspringt. Mit anderen Worten, der Rückgabetyp ermöglicht die Ableitung der Typen für den Aufruf collect(…)
, nicht jedoch für den vorhergehenden Aufruf map(…)
. (Siehe auch diese Antwort )
Aber es funktioniert für geschachtelte Methodenaufrufe, so dass die folgende neu geschriebene Methode kompiliert werden kann:
%Vor% Dennoch müssen Sie die Semantik Ihres Codes überdenken. Der Typparameter einer Methode, der nur beim Rückgabetyp angezeigt wird, kann nicht korrekt sein, da er impliziert, dass " was auch immer der Aufrufer für diesen Typparameter ersetzt, die Methode das richtige zurückgibt ". Da die Methodenimplementierung nicht weiß, was der Aufrufer annimmt, ist dies unmöglich. Nur die Rückkehr von null
oder eine leere Liste funktioniert korrekt, was wenig nutzt.
Wenn Sie ein ?
haben, ist es nicht gleich einem anderen ?
, d. h. der Compiler sieht
als Übereinstimmung für
%Vor%, da nicht davon ausgegangen werden kann, dass die beiden ?
gleich sind. Es könnte
Wenn Sie den Cast durchführen, verdecken Sie die Constraint, damit sie übereinstimmen kann.
Ich nehme an, dass der in der statischen Methode definierte generische Typ nicht mit dem in der Klasse definierten generischen Typ übereinstimmt. Sie sollten die Methode lookup
nicht statisch machen können, damit sie mit dem gleichen Typ übereinstimmt, der in der allgemeinen Deklaration auf Klassenebene definiert ist:
Tags und Links java java-8 type-inference java-stream