Java 8: convert lambda to a Method instance with closure included

前端 未结 2 1716
野的像风
野的像风 2020-12-16 00:59

(This is difficult to search because results are all about \"method reference\")

I want to get a Method instance for a lambda expression for use with a

2条回答
  •  春和景丽
    2020-12-16 01:13

    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 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 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 lambda;
      public LambdaAccessor(Function lambda) {
        this.lambda = lambda;
      }
    
      @Override public Object invoke(Object o, Object[] os) {
        return lambda.apply(os);
      }
    }
    

提交回复
热议问题