Java 8:将lambda转换为包含clousure的Method实例 [英] Java 8: convert lambda to a Method instance with clousure included
问题描述
(这很难搜索,因为结果都是关于方法参考)
(This is difficult to search because results are all about "method reference")
我想要一个方法
lambda表达式的实例,用于基于遗留反射的API。应该包含clousure,因此调用 thatMethod.invoke(null,...)
应该与调用lambda具有相同的效果。
I want to get a Method
instance for a lambda expression for use with a legacy reflection-based API. The clousure should be included, so calling thatMethod.invoke(null, ...)
should have the same effect as calling the lambda.
我查看了 MethodHandles.Lookup ,但它似乎只与逆转换相关。但我想 bind
方法可能有助于包含clousure?
I have looked at MethodHandles.Lookup, but it only seems to be relevant for the reverse transform. But I guess the bind
method may help to include the clousure?
编辑:
说我有lambda experssion:
Say I have am lambda experssion:
Function<String, String> sayHello = name -> "Hello, " + name;
我有一个遗留框架(Spel ),其API类似
and I have a legacy framework (SpEL) that has an API like
registerFunction(String name, Method method)
调用给定的方法
,不带这个
参数(即假定为静态的方法)。所以我需要一个特殊的方法
实例,其中包括lambda逻辑+ clousure数据。
which will call the given Method
with no this
argument (i.e. Method assumed to be static). So I'll need to get a special Method
instance that includes the lambda logic + the clousure data.
推荐答案
如果你找不到优雅的方式,这就是丑陋的方式( Ideone 一>)。涉及反射时的常用警告:可能在将来的版本中中断等。
In case you don't find an elegant way, here is the ugly way (Ideone). Usual warning when reflection is involved: may break in future releases etc.
public static void main(String[] args) throws Exception {
Function<String, String> sayHello = name -> "Hello, " + name;
Method m = getMethodFromLambda(sayHello);
registerFunction("World", m);
}
static void registerFunction(String name, Method method) throws Exception {
String result = (String) method.invoke(null, name);
System.out.println("result = " + result);
}
private static Method getMethodFromLambda(Function<String, String> lambda) throws Exception {
Constructor<?> c = Method.class.getDeclaredConstructors()[0];
c.setAccessible(true);
Method m = (Method) c.newInstance(null, null, null, null, null, 0, 0, null, null, null, null);
m.setAccessible(true); //sets override field to true
//m.methodAccessor = new LambdaAccessor(...)
Field ma = Method.class.getDeclaredField("methodAccessor");
ma.setAccessible(true);
ma.set(m, new LambdaAccessor(array -> lambda.apply((String) array[0])));
return m;
}
static class LambdaAccessor implements MethodAccessor {
private final Function<Object[], Object> lambda;
public LambdaAccessor(Function<Object[], Object> lambda) {
this.lambda = lambda;
}
@Override public Object invoke(Object o, Object[] os) {
return lambda.apply(os);
}
}
这篇关于Java 8:将lambda转换为包含clousure的Method实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!