2012-01-11 46 views
41

我在研究JDK 1.7的新功能,但我无法得到MethodHandle的设计目的?我理解(直接)调用静态方法(以及在这种情况下直接使用Core Reflection API)。我也理解(直接)调用虚拟方法(非静态,非最终)(以及使用需要通过类层次结构obj.getClass().getSuperclass()的Core Reflection API)。非虚拟方法的调用可以被视为前者的特例。MethodHandle - 它是什么?

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

但是,什么是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的替代方式。

+0

不行,绝对不行。该帖子已超过3年。许多框架开发人员正在密切关注MH,并调用动态方法和方法来使用它们来帮助开发人员。 – kittylyst 2012-01-11 22:40:05

+0

你能举一个这样的例子吗?对于使用Core Reflection API不可能实现的MethodHandle有什么可能? – alexsmail 2012-01-12 02:45:25

+1

例如,与安全管理器进行交互。 setAccessible()会在安全管理器下杀死你,而Lookup机制是完全安全的。查找还可以让您在上下文中创建MH,然后将该参考传递给非特权上下文。 – kittylyst 2012-01-12 07:30:48

回答

29

这是前体到Java 8提供MethodHandles语言支持。您将能够直接引用方法,MethodHandles将支持该方法。

什么你可以用MethodHandles做的是咖喱的方法,改变类型的参数,并改变它们的顺序。

方法处理可以处理的方法和字段。

其中MethodHandles做另一个窍门是使用原始的直接(而不是通过包装器)

MethodHandles可以比使用反射,因为在JVM e.g它们可以被内联更直接的支持更快。它使用新的invokedynamic指令。 MethodHandle的

+6

在另外,在做调用当踪迹是比反射更好。作为一个缺点,你不能调用通过反射一个methodhandle(但另一种方式圆) – mihi 2012-01-11 19:52:10

+8

'MethodHandle's不要使用invokedynamic指令。但是,有一个关系的其他方法:将invokedynamic指令通过“另一种技巧在很大程度上依赖于'MethodHandle's – Holger 2014-03-17 10:01:27

+2

@Peter究竟你是什么意思它。 MethodHandles做的是使用原始直接(而不是通过包装)“? – Geek 2014-08-07 15:29:39

10

java.lang.reflect.Method在内存方面相对较慢和昂贵。方法句柄应该是一种“轻量级”的方式,将指针传递给JVM有可能优化的函数。从JDK8方法句柄没有那么好的优化,并且lambda可能最初是以类的形式实现的(就像内部类一样)。

+0

@tackline,我知道'java.lang.reflect.Method'是比较慢的。我也看到了一些统计量表明,'MehodHandle'不那么快。所以,主要的原因是性能?什么是Λ是用Java做什么?LAMBDA演算是完全不同的编程方法... – alexsmail 2012-01-11 17:40:36

+0

@tackline,请看上面我的更新。 – alexsmail 2012-01-11 20:38:29

+0

多了一个更新补充。 – alexsmail 2012-01-11 22:04:15

7

觉得作为一个现代的,更灵活,更类型安全做反思的方式。

这是目前在其生命周期的早期阶段 - 但随着时间的推移有可能被优化成为必须比反射快 - 到如此地步,它可以成为快如常规的方法调用。

+0

这是对Java基本理念给唯一可能的一种方式为Java程序员做事。我知道在引入JDK 1.5的一些功能改变了这些,但在JDK 1.5的功能是为Java程序员(当然,我知道,他们中的一些是有争议的)是有用的,据我现在所看到的普通的Java开发者MethodHandle功能是没有用的。 – alexsmail 2012-01-11 22:00:16

相关问题