Java 8 scheint Klassen zu generieren, die Lambda-Ausdrücke darstellen. Zum Beispiel kann der Code:Transformieren von Lambdas in Java 8
Runnable r = app::doStuff;
Manifests, grob, wie:
// $FF: synthetic class
final class App$$Lambda$1 implements Runnable {
private final App arg$1;
private App$$Lambda$1(App var1) {
this.arg$1 = var1;
}
private static Runnable get$Lambda(App var0) {
return new App$$Lambda$1(var0);
}
public void run() {
this.arg$1.doStuff();
}
}
Wie ich das verstehen, wird der Code zur Laufzeit generiert. Angenommen, man wollte Code in die run
-Methode der obigen Klasse einfügen. Experimente ergeben bisher eine Mischung aus NoClassDefFound
und VerifyError
:
$ java -version
java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)
Dies ist auch vor dem Drücken einer beliebigen neuen Bytecode in die Klasse:
java.lang.NoClassDefFoundError: App$$Lambda$2
at App$$Lambda$2/1329552164.run(Unknown Source)
at App.main(App.java:9)
Caused by: java.lang.ClassNotFoundException: App$$Lambda$2
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 2 more
Das gegen läuft.
Wird das erwartet? Riecht wie ein JDK-Fehler, aber ich bin glücklich, dass ich mich geirrt habe!
Hier ist ein Github repo illustrating the behavior
Das gleiche Verhalten gilt für die neueste Version des JDK, '1.8.0_65' – thetwan
Der Prüffehler zeigt an, dass Sie einen fehlerhaften Bytecode erstellt haben. Hast du versucht, den Code zu debuggen? In welcher Aktion tritt der Fehler auf? –
Dies ist bei einem Retransform-Aufruf. Der ClassTransformation-Callback wird in diesem Fall nicht einmal aufgerufen! Um genau zu sein, geschieht dies auf 'Instrumentation # retransformClasses (...)' – thetwan