Ich habe Code mit einer Methodenreferenz, die zur Laufzeit kompiliert und fehlschlägt.LambdaConversionException mit Generics: JVM-Bug?
Die Ausnahme ist so:
Caused by: java.lang.invoke.LambdaConversionException: Invalid receiver type class redacted.BasicEntity; not a subtype of implementation type interface redacted.HasImagesEntity
at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:233)
at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303)
at java.lang.invoke.CallSite.makeSite(CallSite.java:289)
Die Klasse ist in etwa so:
class ImageController<E extends BasicEntity & HasImagesEntity> {
void doTheThing(E entity) {
Set<String> filenames = entity.getImages().keySet().stream()
.map(entity::filename)
.collect(Collectors.toSet());
}
}
die Ausnahme ausgelöst wird versucht Einheit :: Dateinamen zu lösen. filename() wird in HasImagesEntity deklariert. Soweit ich das beurteilen kann, erhalte ich die Ausnahme, weil das Löschen von E BasicEntity ist und die JVM nicht andere Grenzen auf E berücksichtigt. Wenn ich die Methodenreferenz als triviales Lambda umschreibe, alles ist gut. Es scheint mir wirklich faul, dass ein Konstrukt wie erwartet funktioniert und sein semantisches Äquivalent explodiert. Könnte das möglicherweise in der Spezifikation sein? Ich bemühe mich sehr, einen Weg zu finden, um im Compiler oder in der Laufzeit kein Problem zu sein, und habe mir nichts einfallen lassen.
Wenn Sie Einheit :: Dateiname schreiben, ich glaube, Sie an den Dateinamen Methode der Instanz, deren beziehen Variablenname Einheit, aber sicher Sie sind also die Dateinamen Methode der durch den Strom bereitgestellt Instanzen zugreifen? – Luciano
@Luciano Ich glaube, 'filename' akzeptiert alles, was in' getImages() 'ist und gibt eine' String' z. 'img -> Einheit.Dateiname (img)'. OP könnte klären. – Radiodef
@Radiodef es sagt "filename() ist auf HasImagesEntity deklariert" (scheint keine Parameter zu nehmen) – Luciano