问题描述
我正在尝试将Method(从文件中读取)转换为lambda表达式,因此我可以忽略缓慢的Method.invoke(...)函数来测量执行该Method所需的时间。
我一直在尝试使用LambdaMetafactory
来实现自己的目标,但是老实说,我读了很多有关如何执行此操作的问题和解释,以至于我什至都不知道自己在做什么。
假设参数和方法构造良好,并且(这是棘手的部分)我必须动态处理涉及不同数量和类型的参数的多个选项:
Object[] parameters = ...;
Method metodin = anotherClass.getmethod();
和界面(抱歉,我稍后会更改名称):
@FunctionalInterface
interface loadedMethod {
Object execute(Object[] params);
}
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.unreflect(metodin);
CallSite callsite = LambdaMetafactory.Metafactory(
lookup,"execute",MethodType.methodType(loadedMethod.class),mh.type(),mh,mh.type()
);
loadedMethod loadedMethod = (loadedMethod) callsite.getTarget().invokeExact();
System.out.println("OUTPUT: " + loadedMethod.execute(parameters)); //Error occurs here
我已经读过post,但我不明白自己在做什么和做错什么。你能帮我吗?
[编辑] 当前错误是:
java.lang.invoke.LambdaConversionException: Incorrect number of parameters for static method invokeStatic Example.myFunction:(int[],int,int)int; 1 captured parameters,3 functional interface method parameters,3 implementation parameters
at java.base/java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:214)
at java.base/java.lang.invoke.LambdaMetafactory.Metafactory(LambdaMetafactory.java:328)
at optimex.ObjectCallable.call(ObjectCallable.java:60)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
解决方法
啊,是的。
您称metalambdafactory错误:
meta lambda工厂的概念是它创建了lambda工厂。
然后,使用工厂创建lambda的实际实例。
第一个MethodType
用于工厂-在您的情况下,您说的是“捕获Object[]
。
您可能不想捕获任何内容-因此正确的MethodType是methodType(loadedMethod.class)
。
CallSite callsite = LambdaMetafactory.metafactory(
lookup,"execute",MethodType.methodType(loadedMethod.class),mh.type(),mh,mh.type()
);
您用invokeWithArguments
调用生成的MethodHandle。
由于工厂不需要其他参数,因此您不应传递它们:
loadedMethod loadedMethod = (loadedMethod) callsite.getTarget().invokeExact();