java - 在实例参数上调用实例方法引用

标签 java dynamic functional-programming java-8 abstract

在 Java 中,给定一个非静态方法引用和一个类的实例,是否可以通过某种方式传达您希望该类实例调用该方法?

伪例子:

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

最佳答案

你不能声明一个方法来调用any类声明的对象的方法,但是如果你使用reflection .
反射方法的缺点是如果方法/访问无效,您可能会在运行时遇到异常。

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


如果您真的想使用 Java 8 并从类型安全中获益来实现您的需求,您应该利用可以在不属于 lambda 的变量上调用方法引用的优势。
但还要注意,函数式接口(interface)接受的参数数量不是可变的。
因此,您应该重载您的通用方法以接受不同数量的参数。

例如,如果您想将一个参数传递给调用的方法,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);
}

如果你需要传递更多的参数,你当然可以创建自己的功能接口(interface):TriFunction , QuadriFunction并以相同的方式重载该方法。

这是一个示例工作代码,说明了这一点:

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() with Function

concatenated=hello world

after adding, list=[hello world]

afer removing, list=[]


methodApply() with BiFunction

substring=hello

关于java - 在实例参数上调用实例方法引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46246000/

相关文章:

java - ExecutorService - 如何在其中一个线程发生异常后中断从主线程调用的线程的执行

java - 如何将spannablestring添加到android中的列表中?

java - 无法循环 MP3 文件

java - AChartEngine,点击获取图表值

c++ - 如果您打算让变量在超出范围后保留,您在哪里调用delete?

mysql - mySQL 中的动态 View 替代方案

过程或函数式编程语言中的单元测试

python - 我如何用 Ruby/Python 编写这个?或者,你能把我的 LINQ 翻译成 Ruby/Python 吗?

ios - 动态更改 UITableView 高度

r - 为什么我不能在 R 中使用 ifelse 分配函数?