方式一:使用接口和匿名内部类
说明:在Java8之前,依赖接口和匿名内部类将方法作为参数传递
代码示例
定义接口,该接口只有一个抽象方法,任何实现此接口的类都必须提供该抽象方法的实现
javainterface Operation { int execute(int a, int b); }创建调用方法,用于接收执行方法所需要的参数和执行方法的实例
javaint performOperation(int a, int b, Operation operation) { return operation.execute(a, b); }调用方法,将参数和执行方法的实现传递进去
javaint actualResult = performOperation(5, 3, new Operation() { @Override public int execute(int a, int b) { return a + b; } });
方式二:使用 Lambda 表达式
说明:在Java8中使用Lambda表达式将方法作为参数传递更加优雅和简洁
代码示例
定义接口,该接口只有一个抽象方法,任何实现此接口的类都必须提供该抽象方法的实现
java@FunctionalInterface interface Operation { int execute(int a, int b); }创建调用方法,用于接收执行方法所需要的参数和执行方法的实例
javaint performOperation(int a, int b, Operation operation) { return operation.execute(a, b); }调用方法,将参数和执行方法的实现传递进去,和方式一不同的是,方式一传递的是匿名内部类,而此方式传递的是Lambda表达式
javaint actualResult = performOperation(5, 3, (a, b) -> a + b);
方式三:使用方法引用
说明:该方式充当调用特定方法的lambda表达式的简写
代码示例
定义执行方法
javapublic class FunctionParameter{ int add(int a, int b) { return a + b; } }调用方法,使用 类名::方法名 将该方法作为引用传递
javaint actualResult = performOperation(5, 3, FunctionParameter::add);
方式四:使用函数类
说明:Java8除了方法引用和Lambda表达式外,还引入了java.util.function包,为常用操作提供了函数式接口。例如,BiFunction是一个函数式接口,表示一个有两个输入参数和一个返回值的函数
代码示例
定义执行方法,下面的代码表示它接收一个以两个Integer值作为输入并返回一个Integer 的函数
javaint executeFunction(BiFunction<Integer, Integer, Integer> function, int a, int b) { return function.apply(a, b); }调用方法,使用 lambda 表达式创建BiFunction的实例,并将其作为参数传递给executeFunction()方法
javaint actualResult = executeBiFunction((a, b) -> a + b, 5, 3);
方式五:使用可调用类
说明:我们还可以使用Callable将方法作为参数传递。Callable接口是java.util.concurrent包的一部分,表示返回结果并可能引发异常的任务。这在并发编程中特别有用。
代码示例
创建接受Callable作为参数的executeCallable()方法。这意味着它接收一个返回Integer的任务
javaint executeCallable(Callable<Integer> task) throws Exception { return task.call(); }call ()方法用于执行任务并返回结果。它可能会引发异常,因此我们需要适当处理它。我们可以使用 lambda 表达式或匿名内部类定义Callable任务。这里,为了简单起见,我们使用 lambda 表达式
javaCallable<Integer> task = () -> 5 + 3;调用executeCallable()方法并将Callable 任务作为参数传递
javaint actualResult = executeCallable(task);
参考文档