java handle_关于java:MethodHandle-这是什么一回事?

我正在研究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语言本身。

UPDATE-2:我读完上面的链接,从那里得到一些引文:

The JVM is going to be the best VM for building dynamic languages, because it already is a dynamic language VM. And InvokeDynamic, by promoting dynamic languages to first-class JVM citizens, will prove it.

Using reflection to invoke methods works great...except for a few problems. Method objects must be retrieved from a specific type, and can't be created in a general way.

...reflected invocation is a lot slower than direct invocation. Over the years, the JVM has gotten really good at making reflected invocation fast. Modern JVMs actually generate a bunch of code behind the scenes to avoid a much of the overhead old JVMs dealt with. But the simple truth is that reflected access through any number of layers will always be slower than a direct call, partially because the completely generified"invoke" method must check and re-check receiver type, argument types, visibility, and other details, but also because arguments must all be objects (so primitives get object-boxed) and must be provided as an array to cover all possible arities (so arguments get array-boxed).

The performance difference may not matter for a library doing a few reflected calls, especially if those calls are mostly to dynamically set up a static structure in memory against which it can make normal calls. But in a dynamic language, where every call must use these mechanisms, it's a severe performance hit.

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

因此,对于Java程序员而言,它实际上是没有用的。我对吗?从这个角度来看,它只能被视为Core Reflection API的替代方法。

不,绝对不是。 该职位已超过3年。 许多框架开发人员正在密切关注MH,并调用动态机制以及使用它们来帮助开发人员的方法。

你能提供一个这样的例子吗? 使用MethodHandle可以做什么,而使用Core Reflection API可以做什么?

例如,与安全管理器进行交互。 setAccessible()将在安全管理器下杀死您,而Lookup机制是完全安全的。 查找还可以让您在可以查看的上下文中创建MH,然后将引用传递给非特权上下文。

实际上,我从未遇到过setAccessible()的问题。 从理论上讲,我可以使用AccessController.doPrivileged(new PrivilegedAction()习惯用法。

看看en.cppreference.com/w/cpp/utility/functional/function也许有帮助

使用MethodHandles可以执行的操作是咖喱方法,更改参数的类型并更改其顺序。

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

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

MethodHandles可能比使用反射更快,因为JVM中有更多直接支持,例如可以内联它们。它使用新的invokedynamic指令。

另外,调用时的堆栈跟踪要比反射好得多。不利的一面是,您不能通过反射调用方法句柄(反之亦然)

MethodHandle不使用invokedynamic指令。但是存在另一种关系:invokedynamic指令在很大程度上依赖MethodHandle。

@Peter" MethodHandles的另一个技巧是使用原始直接(而不是通过包装器)"到底是什么意思?

@Geek如果使用方法,它将包装参数并返回值。即在double method(double d) { return d; }上调用它会创建至少两个对象。使用MethodHandles,它足够聪明,从而无需在调用时包装参数或返回值,即使从概念上讲它需要Object...并返回Object

这是因为它不使用invokedynamic,而是为此而创建的invokepolymorphic。如果查看字节码,您会发现invokedynamic不仅存储了原始的,被忽略的签名,还存储了您调用它的签名。

实际上,它看起来像是在字节码中有一个方法double MethodHandle.invokeExact(double)。

就内存而言,java.lang.reflect.Method相对较慢且昂贵。方法句柄应该是将指针传递给JVM有机会优化的函数的"轻量级"方法。从JDK8开始,方法的句柄还没有得到很好的优化,lambda可能最初是根据类实现的(就像内部类一样)。

@tackline,我知道java.lang.reflect.Method相对较慢。我还看到了一些统计数据,显示MehodHandle的速度不是那么快。那么,主要原因是性能? Lambda在Java中做什么? Lambda演算是完全不同的编程方法...

@tackline,请查看上面的更新。

添加了一个更新。

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

它目前处于生命周期的早期阶段-但随着时间的流逝,有可能需要对其进行优化以使其必须比反射更快-以至于它可以像常规方法调用一样快。

仅提供一种可能的方式来为Java程序员提供服务是违背Java基本哲学的。我知道在JDK 1.5中引入一些功能可以改变这些功能,但是JDK 1.5中的功能对Java程序员很有用(嗯,我知道,其中一些有争议),到目前为止,对于常规Java Developer,MethodHandle功能没有用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值