在实例参数上调用实例方法参考

时间:2017-09-15 19:02:05

标签: java dynamic functional-programming java-8 abstract

在Java中,给定非静态方法引用和类的实例,可能会以某种方式传达您希望该类实例调用该方法的信息吗?

伪示例:

public Object methodApply(Function<Object,Object> method, Object instance, List<Object> args) {
    return instance.method(args);
}

1 个答案:

答案 0 :(得分:3)

您无法声明在使用任何类声明的对象上调用任何方法的方法,但是如果您使用reflection。 反射方法的缺点是,如果方法/访问无效,您可能会在运行时获得异常。

使用Java 8,您可以传递任何 method reference来实现功能接口(它只是lambda表达式的替代方案)。
限制是此方法引用必须符合功能接口描述符。

如果你真的想要使用Java 8并从类型安全中受益来实现你的需要,你应该利用你可以对不属于lambda的变量调用方法引用。
但请注意,功能接口接受的参数数量不可变 所以你应该重载你的泛型方法来接受不同数量的参数。

例如,如果要将一个参数传递给调用的方法,methodApply()应该有一个Function<T,R>参数:

public static <T, R> R methodApply(Function<T, R> function, T arg) {
  return function.apply(arg);
}

但是如果你还希望能够将两个参数传递给被调用的方法,那么methodApply()应该被重载并且具有BiFunction<T, U, R>参数:

public static <T, U, R> R methodApply(BiFunction<T, U, R> function, T argOne, U argTwo) {
  return function.apply(argOne, argTwo);
}

如果您需要传递更多参数,您当然可以创建自己的功能接口:TriFunctionQuadriFunction并以相同的方式重载方法。

以下是一个示例工作代码,说明了:

import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;

public class FunctionHelper {

    public static void main(String[] args) {

      System.out.println("methodApply() with Function" + System.lineSeparator());
      // String.concat
      String oneString = "hello";
      String concatenated = methodApply(oneString::concat, " world");
      System.out.println("concatenated="+ concatenated);

      // List add/remove
      List<String> list = new ArrayList<>();
      methodApply(list::add, concatenated);
      System.out.println("after adding, list="+list);
      methodApply(list::remove, concatenated);
      System.out.println("afer removing, list="+list);

      System.out.println("---------------------------"+ System.lineSeparator());

      System.out.println("methodApply() with BiFunction" + System.lineSeparator());
      // String.substring
      oneString = "hello world";    
      System.out.println("substring=" + methodApply(oneString::substring, 0, 6));
    }

    public static <T, R> R methodApply(Function<T, R> function, T arg) {
      return function.apply(arg);
    }

    public static <T, U, R> R methodApply(BiFunction<T, U, R> function, T argOne, U argTwo) {
      return function.apply(argOne, argTwo);
    }

}

输出:

  

带有函数的methodApply()

     

concatenated = hello world

     

添加后,list = [hello world]

     

删除,列表= []

           

带BiFunction的methodApply()

     

子=你好