MethodHandle的MethodType转换接受Array Object参数

时间:2015-01-29 21:41:40

标签: java invokedynamic methodhandle

我想将String.startsWith(String, String)boolean调整为(String[])boolean,以便它可以接受String[]个参数,其中前两个参数将映射到{{1} }}。因此,我在下面写了示例代码:

(String, String)

MethodHandle test =MethodHandles.publicLookup().findVirtual(String.class, "startsWith", MethodType.methodType(boolean.class, String.class)); String[] myArgs = {"result", "data", "sijie"}; MethodHandle adapt = test.asSpreader(String[].class, 2); System.out.println("Adapt... "+ adapt.type().toString()); System.out.println("Compare Result: "+ adapt.invokeExact(myArgs)); //Expect to return false. MethodHandle首先适应了String.startsWith。但结果显示boolean (String[])失败。

adapt.invokeExact

stacktrace中的新Adapt... (String[])boolean Exception in thread "main" java.lang.invoke.WrongMethodTypeException: expected (String[])boolean but found (String[])Object at java.lang.invoke.Invokers.newWrongMethodTypeException(Invokers.java:349) at java.lang.invoke.Invokers.checkExactType(Invokers.java:360) at org.bytecode.generation.sample.App.main(App.java:78) 对象非常混乱。任何人都可以就如何修复它提出一些建议吗?

感谢

这个问题可以是抽象的:  如何调整只接受(String[])的{​​{1}}以便它可以接受Methodhandle个参数?

2 个答案:

答案 0 :(得分:2)

问题在于invokeExact调用 - 因为invokeExact是签名多态,您需要使用强制转换显式指定返回类型:

System.out.println("Compare Result: "+ (boolean)adapt.invokeExact(myArgs));

这就是堆栈跟踪尝试用expected (String[])boolean but found (String[])Object告诉你的 - 因为你没有转换为booleanjavac假设方法句柄的类型为(String[])Object 1}},但在运行时,它的类型为(String[])boolean。 (顺序可能令人困惑。可以把它想象为“给定方法句柄,我期望在invokeExact的编译时记录什么类型?”

另见我对Why can't I .invokeExact() here, even though the MethodType is OK?的回答。 (该问题涉及子类型和涉及的解决方案asType以及添加演员,但信息类似。)

答案 1 :(得分:0)

经过多次重试后得到解决方案。

MethodHandle guard =MethodHandles.publicLookup().findVirtual(String.class, "startsWith", MethodType.methodType(boolean.class, String.class));
String[] myArgs = {"result", "data", "sijie"};
guard.invokeWithArguments(Arrays.copyOfRange(myArgs, 0, guard.type().parameterCount()));