Java Lambda及InvokedDynamic调用探秘(二
2018-01-03 本文已影响29人
gancheng_wxh
在第一篇中我们了解到实例中的Lambda最终会生成一个静态方法,通过invokeDynamic指令最后在执行过程中最终会调用到这个静态方法。
在这篇中我们将深入分析一下oracle jdk内部是如何构建出bootstrap_method的,以及如何创建出自动新增加的类的。
我们可在LambdaMetaFactory的metafactory方法中添加一个断点。
metafactory断点.png运行时信息如下面两图。
metafactory运行参数信息.png metafactory执行时参数信息2.png
这些参数中,除了caller参数外,其它都是从java类文件中可以直接获取到的或包装了而已。没有印象可以查看第一篇文章。
跟踪到InnerClassLambdaMetaFactory的实例创建过程。
InnerClassMetaFactorystaticinit.png上篇文章中Dump出InnerClass的开关参数就是在InnerClassLambdaMetaFactory的类静态初始化语句块中设置的。
继续跟踪到可以看到执行到下列代码块。
lambdaClassName.png
从上图可以看出LambdaClasName的值是如何生成的。ImplMethodName就是“lambda$main$0”。这名称就是第一章中提到到自动添加的方法名。
跟进到InnerClassLambdaFactory的buildCallSite方法中,可以看到如下逻辑:
Constructor.png继续跟踪,可以看到如下代码。
sambuildview.png继续跟踪到ForwardingMethodGenerator类的generate方法中。此方法中通过方法:visitMethodInsn生成调用
lambda$main$0静态方法的字节代码。
最终,dump出InnerClass的地方是InnerClassLambdaMetaFactory的buildCallSite方法中。
dumpclass.png