我正在研究 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 语言本身的生活。
UPDATE-2:我读完上面的链接,从那里引用一些:
JVM 将成为构建动态语言的最佳 VM,因为它已经是动态语言 VM。InvokeDynamic 通过向一流的 JVM 公民推广动态语言,将证明这一点。
使用反射来调用方法效果很好......除了一些问题。方法对象必须从特定类型中检索,不能以一般方式创建。<...>
...反射调用比直接调用慢很多。多年来,JVM 在快速实现反射调用方面做得非常好。现代 JVM 实际上会在幕后生成一堆代码,以避免旧 JVM 处理的大量开销。但简单的事实是,通过任意层数的反射访问总是比直接调用慢,部分原因是完全通用的“调用”方法必须检查并重新检查接收器类型、参数类型、可见性和其他细节,但是还因为参数必须都是对象(因此原语被对象装箱)并且必须作为数组提供以涵盖所有可能的参数(因此参数被装箱)。
对于执行一些反射调用的库来说,性能差异可能并不重要,特别是如果这些调用主要是在内存中动态设置一个静态结构,它可以对其进行正常调用。但是在动态语言中,每次调用都必须使用这些机制,这会严重影响性能。
http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html
因此,对于 Java 程序员来说,它本质上是无用的。我对吗?从这个角度来看,它只能被认为是Core Reflection API的替代方式。
UPDATE-2020:确实,MethodHandle 可以被认为是核心反射 API 的更强大的替代方案。从 JDK 8 开始,还有一些使用它的 Java 语言特性。