我想将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
个参数?
答案 0 :(得分:2)
问题在于invokeExact
调用 - 因为invokeExact
是签名多态,您需要使用强制转换显式指定返回类型:
System.out.println("Compare Result: "+ (boolean)adapt.invokeExact(myArgs));
这就是堆栈跟踪尝试用expected (String[])boolean but found (String[])Object
告诉你的 - 因为你没有转换为boolean
,javac
假设方法句柄的类型为(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()));