Java 8似乎会生成表示Lambda表达式的类。例如,下面的代码:
Runnable r = app::doStuff;
表现为清单文件:
// $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();
}
}
据我所理解,这段代码是在运行时生成的。现在,假设某人想要将代码注入上述类的run
方法中。目前的实验结果产生了一些NoClassDefFound
和VerifyError
的混合:
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
正在运行的内容是:
$ 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)
在将任何新的字节码推入类之前,就已经出现了这种情况。
这是预期的吗?感觉像是JDK的bug,但我很高兴能够被证明是错误的!
这里有一个Github仓库展示了这种行为
null
来表示你不想转换该类。 - Rafael Winterhalterinvokedynamic
指令或目标方法来实现。没有理由去检测lambda表达式或方法引用的短暂匿名类。 - Holger