Warum kompiliert dieses Java 8-Stream-Beispiel nicht?

8

Ich versuche herauszufinden, warum dieser Code nicht auf JDK 1.8.0_45 kompiliert:

%Vor%

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.

    
Stijn Van Bael 02.06.2015, 14:55
quelle

3 Antworten

8

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.

    
Holger 02.06.2015, 15:25
quelle
7

Wenn Sie ein ? haben, ist es nicht gleich einem anderen ? , d. h. der Compiler sieht

nicht %Vor%

als Übereinstimmung für

%Vor%

, da nicht davon ausgegangen werden kann, dass die beiden ? gleich sind. Es könnte

sein %Vor%

Wenn Sie den Cast durchführen, verdecken Sie die Constraint, damit sie übereinstimmen kann.

    
Peter Lawrey 02.06.2015 15:10
quelle
1

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:

%Vor%     
John Vint 02.06.2015 15:07
quelle