我一直在阅读关于java8 lambdas implementation http://fr.slideshare.net/czechscala/java-8-under-the-hood
的演示文稿LambdaMetaFactory包含用于将lambda表达式转换为功能接口对象的引导方法。
这些bootstrap methods
是什么,它们与invokedynamic
有关吗?
答案 0 :(得分:5)
invokedynamic 是用于在JVM中调用任意方法的字节码操作。在编译时,要调用和执行的确切方法是未知的。相反,它是通过实现CallSite的对象来计算的。因此,动态调用中的 dynamic 。
CallSite对象以及其他任何对象都必须实例化。 引导程序方法是一种实例化CallSite对象的方法。
每个 invokedynamic 具有已知的 bootstrap方法作为其编译时参数。每当首次处理invokedynamic时,都会调用适当的引导程序方法。 boostrap方法执行的结果是创建了一个CallSite对象。然后,此CacheSite对象被JVM缓存并与给定的invokedynamic操作关联。从现在开始,每当要执行特定的invokedynamic调用时,就会使用缓存的CallSite实例来解析被调用的方法。
大多数boostrap方法不是由最终Java程序员直接编写的。但是,这并不意味着它们是一些罕见的模糊机制。每当在源代码中使用特定的Java语句时,它们都是由javac编译器创建的。我想到了字符串连接或lambda表达式。
例如,lambda表达式可以实现为内部类。实际上,lambda是作为使用内部类的简写形式呈现给程序员的。但是,出于性能原因,实际的javac实现通过在静态方法下生成lambda代码并使用invokedynamic调用此方法来避免内部类。
要更直接,更令人印象深刻地使用invokedynmaic,我建议Charles Nutter blog关于他如何使用这种机制优化JRubby呼叫站点。尽管编写RubyVM并不是Java程序员的日常活动,但它确实为如何正确使用ivokedynamic开辟了视野。
答案 1 :(得分:3)
班上只有两种方法:https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/LambdaMetafactory.html
metafactory()
和altMetafactory()
。两者都提到了“invokedynamic调用站点的引导方法”。
我的理解是,当调用的目标是lambda表达式时,实现invokedynamic
操作码处理的代码最终会使用其中一个。
在此上下文中,术语“引导”意味着它准备好以后实际执行作业所需的一切。