在Java中将任何方法作为参数传递的功能接口

时间:2019-01-17 18:55:49

标签: java methods lambda functional-programming

我正在尝试编写一个带有2个参数的方法-类引用和该类中方法的引用。方法本身的返回类型应该是该类的方法返回类型是什么。例如:

public <T> T myMethod (Class<?> c, <reference to a method m in class c>), where m returns something of type <T>.

也就是说,在我的代码中,我应该能够将上述方法调用为:

myMethod (SomeClass.class, x -> x.someMethod(param1, param2))

请注意,SomeClass可以是任何类,而someMethod可以是该类中具有任意数量参数的任何方法。

我可以肯定的是,使用Java 8中的lambda和功能接口可以做到这一点,但不清楚如何放置它。

2 个答案:

答案 0 :(得分:6)

函数接口方法需要采用与命名类c相同类型的一个参数,因此您需要为该类定义一个通用类型,将其称为C

功能接口方法需要返回类型T的值,但可以重命名R来表示返回类型。

这意味着您的功能界面可以是:Function<C, R>

您的完整方法声明为:

public <C, R> R myMethod(Class<? extends C> clazz, Function<C, R> method)

可以完全按照您的显示来调用它。

演示

public class Test {
    public static void main(String[] args) throws Exception {
        Test t = new Test();
        String param1 = "Foo", param2 = "Bar";

        String result = t.myMethod(SomeClass.class, x -> x.someMethod(param1, param2));

        System.out.println(result);
    }
    public <C, R> R myMethod(Class<? extends C> clazz, Function<C, R> method) throws Exception {
        C obj = clazz.getConstructor().newInstance();
        return method.apply(obj);
    }
}

class SomeClass {
    public SomeClass() {}
    public String someMethod(String param1, String param2) {
        return param1 + " + " + param2 + ": " + this;
    }
}

输出

Foo + Bar: test.SomeClass@5594a1b5

答案 1 :(得分:0)

您尝试做的事情不可能立即实现。意思是,如果没有对方法的直接反射访问,就不能引用该方法。

实际上,myMethod(MyClass.class, myClass -> myClass.Hello)绝对不是  一个很好的解决方案。考虑一下,您在哪里需要这个?如果该方法是静态的,则无论如何都可以调用它,如果不是,则只需要一个实例。

但是,您可以做的是找到您的方法并通过反射api调用它:

public Object myMethod(Class<?> clazz) {
    return clazz.getDeclaredMethod("name_of_method", ... /*Any parameters*/).invoke(/*params*/);
}