我正在研究JDK 1.7的新功能,我无法得到它为MethodHandle设计的内容?我理解(直接)静态方法的调用(以及在这种情况下直接使用Core Reflection API)。我也理解(直接)调用虚方法(非静态,非最终)(以及使用需要通过Class的层次结构obj.getClass().getSuperclass()
的Core Reflection API)。非虚方法的调用可以视为前者的特殊情况。
是的,我知道存在重载问题。如果要调用方法,则必须提供确切的签名。您无法以简单的方式检查重载方法。
但是,MethodHandle是什么? Reflection API允许您“查看”对象内部,而无需任何预先假设(如实现接口)。您可以出于某种目的检查对象。但是MethodHandle的设计是什么呢?我应该何时何地使用它?
更新:我现在正在阅读这篇http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html文章。根据它,主要目标是简化在JVM上运行的脚本语言的生命,而不是Java语言本身。
更新-2:我读完了上面的链接,从那里引用了一些引文:
JVM将成为构建动态语言的最佳VM,因为它已经是一个动态语言VM。而InvokeDynamic通过向一流的JVM公民推广动态语言,将证明这一点。
使用反射来调用方法效果很好......除了一些问题。必须从特定类型检索方法对象,并且不能以一般方式创建。<...>
...反射调用比直接调用慢很多。多年来,JVM已经非常擅长快速反映调用。现代JVM实际上在幕后生成了一堆代码,以避免处理大量开销的旧JVM。但简单的事实是,通过任意数量的层反射访问总是比直接调用慢,部分原因是完全通用的“调用”方法必须检查并重新检查接收器类型,参数类型,可见性和其他细节,但因为参数必须都是对象(所以原语是对象框),并且必须作为一个数组提供,以涵盖所有可能的arities(所以参数得到数组框)。
对于执行少量反射调用的库,性能差异可能无关紧要,特别是如果这些调用主要是为了在内存中动态设置静态结构,可以进行正常调用。但是在动态语言中,每次调用必须使用这些机制,这是一个严重的性能损失。
http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html
因此,对于Java程序员来说,它基本上是无用的。我对吗?从这个角度来看,它只能被视为Core Reflection API的替代方式。
您可以使用MethodHandles做的是咖喱方法,更改参数类型并更改其顺序。
方法句柄可以处理方法和字段。
MethodHandles做的另一个技巧是使用原始直接(而不是通过包装)
MethodHandles可以比使用反射更快,因为JVM中有更多的直接支持,例如它们可以内联。它使用新的invokedynamic指令。
java.lang.reflect.Method
在内存方面相对缓慢且昂贵。方法句柄应该是一种“轻量级”方式,可以将指针传递给JVM有机会优化的函数。从JDK8开始,方法句柄的优化程度不高,lambdas最初可能是以类的形式实现的(如内部类)。
将MethodHandle视为一种现代的,更灵活,更安全的反射方式。
它目前处于生命周期的早期阶段 - 但随着时间的推移,有可能被优化成必须比反射更快 - 以至于它可以变得像常规方法调用一样快。