方法处理 - 它到底是什么?

2022-08-31 19:37:01

我正在研究JDK 1.7的新功能,但我无法获得MethodHandle的设计目的?我理解静态方法的(直接)调用(以及在这种情况下直接使用核心反射API)。我还理解虚拟方法(非静态,非最终)的(直接)调用(以及使用需要通过类的层次结构的核心反射API)。非虚拟方法的调用可以作为前一种方法的特殊情况。obj.getClass().getSuperclass()

是的,我知道重载存在问题。如果要调用方法,则必须提供确切的签名。您无法以简单的方式检查重载方法。

但是,MethodHandle是关于什么的呢?反射 API 允许您“查看”对象内部,而无需任何预先假设(如实现的接口)。您可以出于某种目的检查对象。但是MethodHandle也设计了什么呢?为什么以及何时应该使用它?

更新:我现在正在阅读这篇 http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html 文章。根据它的说法,主要目标是简化在JVM上运行的脚本语言的生活,而不是Java语言本身。

更新-2:我最后阅读了上面的链接,从那里引用了一些:

JVM将成为构建动态语言的最佳VM,因为它已经是一个动态语言VM。InvokeDynamic通过将动态语言推广到一流的JVM公民,将证明这一点。

使用反射来调用方法效果很好...除了几个问题。方法对象必须从特定类型中检索,并且不能以常规方式创建。<...>

...反射调用比直接调用慢得多。多年来,JVM已经非常擅长快速进行反射调用。现代JVM实际上在幕后生成了一堆代码,以避免旧JVM处理的大部分开销。但简单的事实是,通过任意数量的层进行反射访问总是比直接调用慢,部分原因是完全生成的“invoke”方法必须检查并重新检查接收器类型,参数类型,可见性和其他细节,但也因为参数必须都是对象(因此基元被对象框化),并且必须作为数组提供以涵盖所有可能的arities(因此参数被数组框化)。

对于执行一些反射调用的库来说,性能差异可能并不重要,特别是如果这些调用主要是在内存中动态设置一个静态结构,它可以针对该结构进行正常调用。但是在动态语言中,每个调用都必须使用这些机制,这是一个严重的性能打击。

http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html

因此,对于Java程序员来说,它本质上是无用的。我说的对吗?从这个角度来看,它只能被视为核心反射API的替代方式。

更新-2020:事实上,MethodHandle可以被认为是Core Reflection API更强大的替代品。从JDK 8开始,还有使用它的Java语言功能。


答案 1

您可以使用MethodHandles做的是咖喱方法,更改参数类型并更改其顺序。

方法句柄可以同时处理方法和字段。

MethodHandles做的另一个技巧是直接使用原始(而不是通过包装器)

方法处理可能比使用反射更快,因为JVM中有更直接的支持,例如它们可以内联。它使用新的调用动态指令。


答案 2

将MethodHandle视为一种现代,更灵活,更安全的反思方式。

它目前处于其生命周期的早期阶段 - 但随着时间的推移,有可能被优化为必须比反射更快 - 以至于它可以变得像常规方法调用一样快。


推荐