1

我的问题如下:我正在尝试使用动态调用,但我在使用 findVirtual 和调用时遇到问题。

Class<?> returnTypeClass = Class.forName("com.etc1.foo.FIXML"); 
MethodHandles.Lookup lookup = MethodHandles.lookup();




MethodType methodType = MethodType.methodType(returnTypeClass ,returnTypeClass); //The method which will be invoked has as a param FIXML object and return a FIXML object

MethodHandle methodHandle = lookup.findVirtual(
                        com.etc2.foo.GMD, 
                        "name_method", 
                        methodType);

我在 findVirtual 中遇到了第一个问题,我得到了一个带有下一个 MethodType (GMD,FIXML)FIXML 的 methodHandle --> 这是不正确的,因为我的方法是“public FIXML name_method(FIXML)”并且 findVirtual 正在创建一个 methodHandle “ public FIXML name_method(GMD,FIXML)",我知道 findVirtual 使用 "com.etc2.foo.GMD" 作为参数。来自这里的第一个问题:如何让 findVirtual 返回 methodHandle FIXML name_method(FIXML)?

第二个问题来自第一个问题,我认为......当我通过methodHandle调用方法时

com.etc1.foo.FIXML fixml;
com.etc1.foo.FIXML fixml2;
fixml2 = (FIXML) methodHandle.invoke(fixml);

我收到以下错误“java.lang.invoke.WrongMethodTypeException:无法将 MethodHandle(GMD,FIXML)FIXML 转换为 (Object)Object”

实际上......我一直在研究其他问题,我尝试了不同的解决方案,但没有任何效果。

4

2 回答 2

0

使用 时,您也可能偶然发现相同的事情invokedynamic,因为 JVM 创建的参数会被传递给bootrstrap方法,在该方法中将进行方法解析。为了规避您发现的错误,您必须从参数中删除应该调用该方法的类MethodType

public static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type) {
    final MethodHandle mh = caller.findVirtual(type.parameterType(0), name, type.dropParameterTypes(0, 1));
    final MutableCallSite callSite = new MutableCallSite(mh);
    return callSite;
}
于 2017-09-11T07:07:29.233 回答
0

在打破我的大脑几个小时后,我得到了答案。findVirtual 方法返回了正确的 MethodHandle,因为添加的参数(GMD,FIXML)实际上是将调用该方法的对象,因此我必须通过以下方式调用该方法:

fixml2Obj = (FIXML) methodHandle.invokeWithArguments((Object) Class.forName("com.etc2.foo.GMD").newInstance(), fixmlObj);

我分享了几个链接,这些链接给了我关于这个的信息:

阅读“方法句柄创建”: http ://docs.oracle.com/javase/7/docs/api/java/lang/invoke/MethodHandle.html

http://octodecillion.com/blog/java-reflection-on-a-message-using-methodhandle/

于 2015-10-29T09:32:54.687 回答