为什么lambda翻译需要生成静态方法?
问题内容:
Lambda转换是一个两步过程, 一个是 :将lambda分解为同一类中的静态方法。
public class Main {
public static void main(String[] args) {
Runnable r = () -> System.out.println("Hello");
System.out.println(Arrays.asList(Main.class.getDeclaredMethods()));
}
}
[ private static void Main.lambda $ main $ 0() ,public static void
Main.main(java.lang.String [])]
二 :生成实现功能接口的类。
System.out.println("A class has been generated: " + r.getClass());
System.out.println("That implements a Functional Interface: " + Arrays.asList(r.getClass().getInterfaces()));
已生成一个类:类Main $$ Lambda $ 1/149928006
实现一个功能接口:[interface java.lang.Runnable]
问题 : 此静态方法需要什么? 为什么不能将lambda主体直接放入接口方法中?就像是:
class Main$$Lambda$1 {
public void run() {
/* Lambda body here */
}
}
问题答案:
除了此处给出的正确答案(因为当前方案更有效,减少lambda的捕获/链接成本并减少代码重复)之外,还有其他一些原因使您的想法根本没有意义。
- 字节码首先从哪里来?lambda代理类是在运行时生成的,而不是在编译时生成的。如果我们将字节码填充到代理类中,则它必须来自某个地方。这意味着我们必须将其放入捕获类文件中 ,然后将 其 复制 到代理类中。在这里,它只存在于捕获类中,我们就完成了。
- 访问控制。如果lambda主体调用私有方法怎么办?通过将其分解为捕获类,它会自动获取捕获类的访问控制上下文(从逻辑上讲,它是其中的一部分。)如果将字节码放入代理类中,则必须做一些额外的魔术才能赋予它正确的访问控制上下文。