首先,从lambda入手。定义并执行一个lambda:
JVM干的事:
- 编译时在调用类中生成一个私有的静态方法,该方法内容就是你的lambda中的内容。
- 运行时将lambda调用者(类),生成隐藏方法的方法信息动态传给metaFactory方法(引导方法)(准确来讲有6个参数,前三个分别是调用者,要实现的方法名称,方法参数类型和返回值,由JVM提供;后三个其中第二个是JVM实现的私有静态方法的方法句柄,由class文件中提供)
metaFactory方法(引导方法)干的事:
- 接收上述JVM的3个参数和class文件提供其余3个参数,构建一个隐藏内部类(该内部类不在字节码文件中)实现相应接口,里面实现的方法直接调用上述JVM生成的隐藏静态方法。
- 返回一个CloseSite对象(调用点),该对象可以直接调用隐藏内部类的相应方法,从而间接调用最终隐藏的静态方法
实现的桥梁 —— JVM的invokedynamic指令
- 该指令由JVM和class文件共同传入参数,调用metaFactory(引导方法,调用的方法信息在class文件中:CONSTANT_InvokeDynamic_info,有具体格式要求),永久绑定结果的CallSite对象,下次直接调用,不再生成新的CallSite对象
- 优点:该指令的作用是为了解决原有的指令方法分派规则完全固化在虚拟机之中的问题,将如何查找目标方法的决定权从虚拟机转移到具体用户代码中(用asm技术动态生成class文件,即可以动态创建类以及方法),让用户有更大的自由度。
- 注:这么讲可能有些难理解,其实jdk之前对匿名内部类完全是由JVM控制和静态实现的,现在jdk8的lambda就可以自己自由地动态生成内部类最后给JVM调用,这样用户的权利就大了许多
- 应用
- lambda —— jdk8
- String “+” (按照参数构建合适的拼接方法并调用和永久绑定以便多次调用) —— jdk9
- 总结:这就是一种权利的转移,民主的体现。