MethodHandle
类的描述中显示的示例在语句WrongMethodTypeException
的调用中抛出mh.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')
时,参数:d
和n
作为Object
数组传递,然后它们与类型{{1}的参数不匹配}}
我知道我可以使用char
代替invokeWithArguments
或invokeExcat
来解决上述问题,但此示例应该按照invoke
的说明进行操作Java 7 API的{1}}。除此之外,MethodHandle
的性能开销与invokeWithArguments
/ invoke
相关。
答案 0 :(得分:2)
你是如何编译的?
对我来说,这听起来像一个已知的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
答案 1 :(得分:0)
div#ext-gen264
要求MH的方法类型描述与参数类型完全匹配。由于MH的方法类型是invokeExact
,所以你想要执行MH,第一个和第二个参数都应该是char。因此,就像那样
(cc)string