我正在学习JDK 1.7的新特性,但是我不明白MethodHandle的设计目的是什么?我理解(直接)调用静态方法(并使用Core Reflection API,在这种情况下很简单)。我也理解(直接)调用虚拟方法(非静态、非final)(并使用Core Reflection API,需要通过类的层次结构
是的,我知道有一个重载问题。如果要调用方法,必须提供精确的签名。你不能轻松地检查重载的方法。
但是,MethodHandle是什么?反射API允许您“查看”对象内部而不做任何假设(如实现接口)。您可以检查对象以达到某种目的。但是MethodHandle是为什么设计的?我应该在什么时候使用它?
obj.getClass().getSuperclass()
)。调用非虚拟方法可以被视为前者的特殊情况。是的,我知道有一个重载问题。如果要调用方法,必须提供精确的签名。你不能轻松地检查重载的方法。
但是,MethodHandle是什么?反射API允许您“查看”对象内部而不做任何假设(如实现接口)。您可以检查对象以达到某种目的。但是MethodHandle是为什么设计的?我应该在什么时候使用它?
更新:我现在正在阅读http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html这篇文章。根据它的说法,主要目标是简化运行在JVM之上的脚本语言的生活,而不是针对Java语言本身。
更新-2:我已经完成阅读上面的链接,以下是一些引用:
“JVM将成为构建动态语言的最佳虚拟机,因为它已经是一种动态语言虚拟机。InvokeDynamic通过将动态语言提升为一流的JVM公民,将证明这一点。”使用反射调用方法效果很好...除了一些问题。方法对象必须从特定类型中检索,并且无法以通用方式创建。......反射调用比直接调用要慢得多。多年来,JVM在使反射调用变快方面做得非常好。现代JVM实际上会在幕后生成大量代码,以避免旧JVM处理的许多开销。但简单的事实是,通过任意数量的层进行反射访问始终比直接调用要慢,部分原因是完全泛型化的“invoke”方法必须检查和重新检查接收器类型、参数类型、可见性和其他详细信息,还因为参数必须全部作为对象提供(因此基元类型被装箱为对象),并且必须作为数组提供以涵盖所有可能的元数(因此参数被装箱为数组)。性能差异对于执行少量反射调用的库可能并不重要,特别是如果这些调用主要是为了动态设置静态内存结构,以便可以对其进行正常调用。但是在动态语言中,每个调用都必须使用这些机制,这对性能造成了严重影响。”http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html
因此,对于Java程序员来说,它基本上是无用的。我是正确的吗?从这个角度来看,它只能被认为是核心反射API的替代方式。
更新-2020年:实际上,MethodHandle可以被认为是核心反射API的更强大的替代方案。从JDK 8开始,还有使用它的Java语言功能。
setAccessible()
函数的问题。理论上,我可以使用AccessController.doPrivileged(new PrivilegedAction())
的惯用语法。 - alexsmail