简体   繁体   English

MethodHandle的MethodType转换接受Array Object参数

[英]MethodType transformation for MethodHandle to accept Array Object paramters

I want to adapt String.startsWith from (String, String)boolean to (String[])boolean , so that it can accepts String[] parameters, in which first two parameters will be mapped to the (String, String) . 我想将String.startsWith(String, String)boolean(String[])boolean ,以便它可以接受String[]参数,其中前两个参数将映射到(String, String) Therefore, I wrote below sample code: 因此,我在下面写了示例代码:

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. 

The MethodHandle to String.startsWith is adapted to the adapt boolean (String[]) at first. String.startsWithMethodHandle适用于adapt boolean (String[]) But the result shows the adapt.invokeExact failure. 但结果显示adapt.invokeExact失败。

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)

The new (String[]) Object in the stacktrace is quite confusing. 堆栈跟踪中的新(String[])对象非常混乱。 Can anyone provide some suggestions on how to fix it? 任何人都可以提供一些如何解决它的建议吗?

Thanks 谢谢

This problem can be abstract as: How to adapt a Methodhandle that only accepts (String, String)boolean so that it can accepts (String[])boolean parameters? 这个问题可以是抽象的:如何调整只接受(String, String)booleanMethodhandle ,以便它可以接受(String[])boolean参数?

The problem is with the invokeExact call -- because invokeExact is signature polymorphic, you need to specify the return type explicitly using a cast: 问题在于invokeExact调用 - 因为invokeExact是签名多态,你需要使用invokeExact显式指定返回类型:

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

That's what the stack trace is trying to tell you with expected (String[])boolean but found (String[])Object -- because you didn't have the cast to boolean , javac assumed the method handle would have type (String[])Object , but at runtime, it had type (String[])boolean instead. 这就是堆栈跟踪试图告诉你的expected (String[])boolean but found (String[])Object - 因为你没有强制转换为booleanjavac假设方法句柄有类型(String[])Object ,但在运行时,它有类型(String[])boolean (The order might be confusing. Think of it like "given the method handle, what type do I expect to have been recorded at compile time for invokeExact ?") (顺序可能会令人困惑。可以把它想象成“给定方法句柄,我希望在编译时为invokeExact录制什么类型的invokeExact ?”)

See also my answer to Why can't I .invokeExact() here, even though the MethodType is OK? 另请参阅我的答案为什么我不能.invokeExact()在这里,即使MethodType没问题? . (That question involved subtyping and the resolution involved asType as well as adding a cast, but the information is similar.) (该问题涉及子类型和解决方案涉及asType以及添加演员,但信息类似。)

Got solution after many retries. 经过多次重试后得到解决方案。

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()));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 找不到符号方法元工厂(查找、字符串、方法类型、方法类型、方法句柄、方法类型) - Can not find symbol method metafactory(Lookup,String,MethodType,MethodType,MethodHandle,MethodType) 如何使用Object []数组调用MethodHandle.invokeExact()? - How to call MethodHandle.invokeExact() with an array of Object[]? 什么是CONSTANT_MethodHandle,CONSTANT_MethodType和CONSTANT_InvokeDynamic? - What are CONSTANT_MethodHandle, CONSTANT_MethodType, and CONSTANT_InvokeDynamic? CONSTANT_MethodHandle_info和CONSTANT_MethodType_info - CONSTANT_MethodHandle_info and CONSTANT_MethodType_info 使用返回类型表示一般的`MethodType`作为任何对象 - Express a general `MethodType` with return type as any object 设置了新的对象参数/对象构造函数 - new object paramters/ object constructor set up 从对象中私有的关键字段获取MethodHandle的列表 - Get List of MethodHandle from key fields which are private in an object 如何使用MethodHandles.Lookup查找数组构造函数MethodHandle? - How do I lookup an array constructor MethodHandle with MethodHandles.Lookup? 为什么来自 MethodHandle 的 WrongMethodTypeException? 我的 object 类型不正确吗? - Why a WrongMethodTypeException from MethodHandle? Is my object type incorrect? 数组变换 - Array transformation
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM