问题标签 [methodhandle]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
2575 浏览

c# - 从接口获取RuntimeMethodHandle?

我有一段反汇编代码,它在一些反射代码方面效果不佳。我不知道如何使它有效,因为我不知道如何使用 MethodHandles 等......我认为这对于反射大师来说应该是一项非常简单的任务,因为(据我所知)唯一的事情需要发生的是“从接口获取方法句柄”?我对么?

以下参数错误.. IProductRepositoryItem.Code 应该是 RuntimeMethodHandle

完整代码:

0 投票
2 回答
1907 浏览

java - MethodHandle 示例在 invokeExact 调用上抛出 WrongMethodTypeException

类描述中显示的示例在调用具有以下描述的语句时MethodHandle抛出 a : 。WrongMethodTypeExceptionmh.invokeExact("daddy",'d','n')(CC)Ljava/lang/String; cannot be called with a different arity as ([Ljava/lang/Object;)Ljava/lang/Object;

MethodHandle对象mh有一个符号类型描述符,对应于:(CC)Ljava/lang/String。但是当我们调用时mh.invokeExact("daddy",'d','n'),参数:dn作为Object数组传递,然后它们与类型的参数不匹配char

我知道我可以使用invokeWithArguments代替invokeExcat或来解决上述问题,但是这个示例应该按照Java 7 APIinvoke的描述中的说明工作。MethodHandle除此之外,与/invokeWithArguments相关的性能开销。invokeinvokeExact

0 投票
4 回答
16029 浏览

java - MethodHandle - 这是什么?

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

0 投票
1 回答
298 浏览

java - 获取重载方法的方法句柄

是否可以在 Java 7 中查找重载方法的方法句柄?

0 投票
1 回答
409 浏览

java-7 - 无法在动态加载类对象上使用 MethodHandle 的 invokeExact

我有一些演示代码如下。

这里是“com.hp.ac.scriptengine.test”。+ generateClassName' 是一个生成的类。我收到的消息如下。

这里第 138 行是mh.invokeExact(my_obj,1);'

mh.invokeExact("daddy",'d','n')...我在 Java 7 API 文档中尝试了该演示代码(例如 ... )。它工作正常。这样的 call( )mh.invokeExact("daddy",'d','n')只是调用. 但是,为什么在我的代码中调用 (Ljava/lang/Object;I)V 而不是 (I)V 呢?(CC)Ljava/lang/String(Ljava/lang/String;CC)Ljava/lang/Stringmh.invokeExact(my_obj,1)

0 投票
2 回答
175 浏览

java - 方法句柄操作

对于我使用 aspectJ 和 invokedynamic 的工作,当切入点与被调用的方法匹配时,我需要将通知编织到方法中。首先,我将脚本中的 invokedynamic-instruction 的引导方法与我自己的进行了交换。现在在我的引导方法中,我想返回一个 CallSite,它首先调用被调用的方法,然后是我定义的建议。

问题是我必须返回一个由 ONE MethodHandle 构建的 CallSite ,其类型签名与原始引导方法中使用的类型签名相同。我考虑过将两个方法句柄(原始 + 建议)组合成一个新的方法句柄,并将其用于返回的 CallSite。但我找不到正确的方法来做到这一点。MethodHandles.foldArguments 似乎很有希望,但它对我不起作用。另一个想法是从调用原始方法句柄和建议的包装方法构建 MethodHandle,但问题是正确的类型签名。

有没有人对我有想法或建议?如何使用建议修补 MethodHandle?

谢谢你。

0 投票
2 回答
2727 浏览

java-7 - Java-7 中的签名多态方法

据我所知,随着 Java 7 中 MethodHandle 的引入,编译器生成的方法重载也随之引入。

MethodHandle的javadoc状态(我已经修剪了示例):

以下是一些使用示例:

上面的每个调用都会生成一个单独的 invokevirtual 指令,其名称为 invoke 和注释中指示的类型描述符。参数类型直接取自实际参数,而返回类型取自立即应用于调用的强制转换。这个演员表可能是一个原始人。如果缺少它,如果调用发生在使用返回值的上下文中,则类型默认为 Object。如果调用作为语句发生,则不可能进行强制转换,并且没有返回类型;通话无效。

实际上,invokeExact 和朋友的行为就好像参数和返回类型的每个可能组合都有一个重载。

我听说 MethodHandles 正在为 Java 8 中的功能做准备,比如 lambdas。(我知道它们对于脚本语言已经很有用了。)

[/介绍]

那么,Java 中是否还有更多这些编译器生成的重载?是否有暗示将来会有更多的它们(例如,使用扩展方法)?为什么首先需要它?仅仅是速度?它如何帮助 lambdas(我认为 lambdas 会编译为匿名内部类)?

简而言之,理由是什么?为什么它们(生成的重载)现在和将来有用?

更新:我在这里称之为编译器生成的重载,Oracle 人称之为签名多态

0 投票
3 回答
7313 浏览

java - 方法句柄性能

我写了一个小基准来测试方法的性能java.lang.invoke.MethodHandlejava.lang.reflect.Method直接调用。

我读到的MethodHandle.invoke()性能几乎与直接调用相同。但是我的测试结果显示了另一个:MethodHandle调用比反射慢大约三倍。我的问题是什么?这可能是一些 JIT 优化的结果吗?

环境: Java 版本“1.7.0_11”Java(TM) SE 运行时环境(构建 1.7.0_11-b21)Java HotSpot(TM) 64 位服务器 VM(构建 23.6-b04,混合模式)操作系统 - Windows 7 64

0 投票
3 回答
3872 浏览

java - 使用 java.lang.invoke.MethodHandle 调用私有方法

如何使用方法句柄调用私有方法?

据我所知,只有两种可公开访问的Lookup实例:

  • MethodHandles.lookup()
  • MethodHandles.publicLookup()

并且两者都不允许不受限制的私人访问。

有非公众Lookup.IMPL_LOOKUP做我想做的事。是否有一些公开的方式来获取它(假设 SecurityManager 允许它)?

0 投票
2 回答
1126 浏览

java - 是否可以直接从java类文件的Constant_Method_REF中获取java.lang.reflection.Method?

我正在使用 BCEL 转换方法字节码来实现匿名内部类风格的方法拦截器,在拦截方法的同时,我需要对被拦截的方法进行一些注解。我使用 BCEL 来拦截除 java 反射之外的方法访问。

现在我的代码可以很好地与没有原始类型的方法一起使用。由于我不知道如何将 Class.getDeclaredMethod 与原始参数类型列表一起使用,因为 getDeclaredMethod 接受 methodName 和 Class[] 数组作为参数。

所以第一个问题是如何做到这一点。

然后我发现在JDK7中,可以通过java类文件中的ldc_w字节码通过CONSTANT_MethodHandle直接获取MethodHandle引用。就像使用 ldc 引用 Java 类一样,如果我可以直接用 ldc_w 引用 java.lang.reflection.Method ,那么我将节省我做反射的时间,并且不会被上面第一个问题中提到的原始类型所困扰. 我试过了,但我没有做到这一点。

所以第二个问题是我可以使用 ldc_w 来引用 java.lang.reflection.Method 吗?

第三个问题是我可以将 MethodHandle 转换为 java.lang.reflection.Method 或相应方法上的注释吗?

谢谢霍尔格,您的回答我几乎完全清楚,但以下问题。我可能会误解您的回答,现在我在运行时遇到异常:

代码如下 //2.5 为数组中的每个元素赋值

convertType2ClassName 如下: