在Java中,给定非静态方法引用和类的实例,可能会以某种方式传达您希望该类实例调用该方法的信息吗?
伪示例:
public Object methodApply(Function<Object,Object> method, Object instance, List<Object> args) {
return instance.method(args);
}
答案 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);
}
如果您需要传递更多参数,您当然可以创建自己的功能接口: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()
concatenated = hello world
添加后,list = [hello world]
删除,列表= []
带BiFunction的methodApply()
子=你好