java - 如何从 Java 方法获取 lambda 表达式

标签 java reflection lambda

假设我有以下方法:

void test () {...}

我通过反射获取这个方法,但是调用它会非常慢,所以我想从中获取Runnable,就像我会写一样

this::test

有什么办法可以实现这一点吗?

最佳答案

I need an implementation for method like this: Runnable toRunnable(Method method); So we are getting a Method and we need to return Runnable

这并不完全等同于 this::test ,因为它也使用 this要绑定(bind)到的实例,因此您还必须传递要绑定(bind)到的实例。但是,您可以使用方法句柄,这是类似 this::test 的底层实现。 .

像这样的类:

public class MyClass {
    public void test() { 
        System.out.println("Test Called");
    }
}

您可以创建此方法:

import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;

...

public static Runnable toRunnable(Method method, Object instance) throws ReflectiveOperationException {
    Lookup lookup = lookup();

    MethodHandle test = lookup.unreflect(method);       
    try {
        return (Runnable) LambdaMetafactory.metafactory(
            lookup,
            "run",
            methodType(Runnable.class, instance.getClass()),
            methodType(void.class),
            test,
            methodType(void.class)
        ).getTarget().invoke(instance);
    } catch (Throwable e) {
        throw new RuntimeException("Should not occur", e);
    }
}

并这样调用它:

Object ref = new MyClass(); // get from somewhere

Runnable result = toRunnable(ref.getClass().getMethod("test"), ref);
result.run(); // prints 'Test Called'

需要注意的是 test方法必须可以从您调用 lookup() 的位置访问,您可以通过传递 Lookup 来解决这个问题手动添加到该方法,并在可以访问 test 的位置创建它方法。或者,如果您使用的是 Java 9,则可以使用 privateLookup(Class<?>, Lookup)相反,但是 Lookup您传递给的需要在与您尝试访问的方法相同的模块中创建。 (简而言之,方法句柄有更多的访问限制)。但如果您尝试访问的方法和类可以公开访问,那么就没有问题。

关于java - 如何从 Java 方法获取 lambda 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50430182/

相关文章:

java regex - 捕获重复组

java - 所有库必须具有确切的版本

java - 通过反射访问classLoader字段

c# - 加载程序集、查找类和调用 Run() 方法的正确方法

java - 如何在 Java 1.7 中编写等效的 lambda 表达式?

java - 如何使用 Opencv 将 PNG 从 Java 类传递到 Android 中的 Native 类

javascript - 对于 JavaFX 的 WebEngine,我如何获得 javascript 错误的通知?

c# - 使用非默认构造函数创建运行时确定类型的对象

c# - 使用 LINQ 或 lambda 表达式获取该值的值和计数

C# 在 lambda 表达式中声明变量