[英]MethodHandle example throws WrongMethodTypeException on invokeExact call
The example shown in the description of the MethodHandle
class throws a WrongMethodTypeException
in the invocation of the statement mh.invokeExact("daddy",'d','n')
with the following description: (CC)Ljava/lang/String; cannot be called with a different arity as ([Ljava/lang/Object;)Ljava/lang/Object;
MethodHandle
类描述中显示的示例在语句mh.invokeExact("daddy",'d','n')
的调用中抛出WrongMethodTypeException
,其描述如下: (CC)Ljava/lang/String; cannot be called with a different arity as ([Ljava/lang/Object;)Ljava/lang/Object;
(CC)Ljava/lang/String; cannot be called with a different arity as ([Ljava/lang/Object;)Ljava/lang/Object;
. 。
The MethodHandle
object mh
has a symbolic type descriptor corresponding to: (CC)Ljava/lang/String
. MethodHandle
对象mh
具有符号类型描述符,对应于: (CC)Ljava/lang/String
。 But when we are invoking mh.invokeExact("daddy",'d','n')
, the arguments: d
and n
are passed as an Object
array and then they are not matching with the arguments of the type char
. 但是当我们调用mh.invokeExact("daddy",'d','n')
,参数: d
和n
作为Object
数组传递,然后它们与char
类型的参数不匹配。
I know that I can resolve the above problem using the invokeWithArguments
instead of the invokeExcat
or the invoke
, but this example was supposed to work as presented in the description of the MethodHandle
of Java 7 API. 我知道我可以使用invokeWithArguments
而不是invokeExcat
或invoke
来解决上述问题,但是这个例子应该如Java 7 API的MethodHandle
描述中MethodHandle
。 Besides that, the invokeWithArguments
has a performance overhead in relation to invoke
/ invokeExact
. 除此之外, invokeWithArguments
与invoke
/ invokeExact
相关的性能开销。
How are you compiling this? 你怎么编译这个?
It sounds suspiciously like a known Eclipse bug to me. 这对我来说听起来像是一个已知的Eclipse bug。
I've just checked with javac and this code: 我刚用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();
}
}
seems to work OK: 似乎工作正常:
ariel-2:src boxcat$ javac scratch/clj/ScratchMH.java
ariel-2:src boxcat$ java scratch/clj/ScratchMH
nanny
ariel-2:src boxcat$
The relevant portion of output from javap seems sane as well: 来自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
requires exact match between the MH's method type description, and the types of arguments. invokeExact
要求MH的方法类型描述与参数类型完全匹配。 Since the MH's method type is (cc)string
, so what you want to execute the MH, both the first and second argument should be char. 由于MH的方法类型是(cc)string
,所以你想要执行MH,第一个和第二个参数都应该是char。 Thus, it is like that 因此,就是这样
``String s = (String)mh.invokeExact('a', 'b')``
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.