Java 8:将lambda转换为包含clousure的Method实例 [英] Java 8: convert lambda to a Method instance with clousure included

查看:202
本文介绍了Java 8:将lambda转换为包含clousure的Method实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(这很难搜索,因为结果都是关于方法参考)

(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆