Java MethodHandle示例在调用invokeExact时抛出错误的MethodTypeException
Java MethodHandle示例在调用invokeExact时抛出错误的MethodTypeException,java,jvm,java-7,invokedynamic,methodhandle,Java,Jvm,Java 7,Invokedynamic,Methodhandle,MethodHandle类描述中显示的示例在调用语句mh.invokeExact(“daddy”,“d”,“n”)时抛出一个ErrorMethodTypeException,描述如下:(CC)Ljava/lang/String;不能使用不同的arity([Ljava/lang/Object;)Ljava/lang/Object;调用 MethodHandle对象mh有一个符号类型描述符,对应于:(CC)Ljava/lang/String,参数:d和n作为对象数组传递,然后它们与char类型的参数
MethodHandle
类描述中显示的示例在调用语句mh.invokeExact(“daddy”,“d”,“n”)
时抛出一个ErrorMethodTypeException
,描述如下:(CC)Ljava/lang/String;不能使用不同的arity([Ljava/lang/Object;)Ljava/lang/Object;
调用
MethodHandle
对象mh
有一个符号类型描述符,对应于:(CC)Ljava/lang/String
,参数:d
和n
作为对象
数组传递,然后它们与char
类型的参数不匹配
我知道我可以使用
invokeWithArguments
而不是invokeExcat
或invoke
来解决上述问题,但是这个示例应该按照Java 7 API的MethodHandle
的描述工作。此外,invokeWithArguments
的性能超过了与invoke
/invokeExact
相关的head是如何编译的
对我来说,这听起来像是一个已知的Eclipse bug
我刚刚用javac检查了一下,下面的代码是:
import java.lang.invoke.*;
public class ScratchMH {
private static ScratchMH instance = null;
public ScratchMH() {
super();
}
private void run() throws Throwable {
Object x, y; String s; int i;
MethodType mt; MethodHandle mh;
MethodHandles.Lookup lookup = MethodHandles.lookup();
// mt is (char,char)String
mt = MethodType.methodType(String.class, char.class, char.class);
mh = lookup.findVirtual(String.class, "replace", mt);
s = (String) mh.invokeExact("daddy",'d','n');
// invokeExact(Ljava/lang/String;CC)Ljava/lang/String;
System.out.println(s);
}
public static void main(String[] args) throws Throwable {
instance = new ScratchMH();
instance.run();
}
}
似乎还可以:
ariel-2:src boxcat$ javac scratch/clj/ScratchMH.java
ariel-2:src boxcat$ java scratch/clj/ScratchMH
nanny
ariel-2:src boxcat$
javap输出的相关部分似乎也很正常:
35: invokevirtual #8 // Method java/lang/invoke/MethodHandles$Lookup.findVirtual:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;
38: astore 6
40: aload 6
42: ldc #9 // String daddy
44: bipush 100
46: bipush 110
48: invokevirtual #10 // Method java/lang/invoke/MethodHandle.invokeExact:(Ljava/lang/String;CC)Ljava/lang/String;
51: astore_3
invokeExact
需要MH的方法类型描述和参数类型之间的精确匹配。由于MH的方法类型是(cc)string
,因此要执行MH,第一个和第二个参数都应该是char。因此,它是这样的
``String s = (String)mh.invokeExact('a', 'b')``
在linux上的OpenJDK 1.7.007中也看到了这个bug