In Java is it possible to, given a non-static method reference, and an instance of the class, somehow communicate that you would like that class instance to invoke that method?
Pseudo example:
public Object methodApply(Function<Object,Object> method, Object instance, List<Object> args) {
return instance.method(args);
}
You cannot declare a method that invokes any method on an object declared with any class but if you use reflection.
The drawback of a reflection approach is you may get exceptions at runtime if the method/access are not valid.
With Java 8, you may pass any method reference but only to implement a functional interface (it is so just an alternative to a lambda expression).
The limitation is that this method reference must be in accordance with the functional interface descriptor.
If you want really to use Java 8 and benefit from type safety to implement your need, you should take advantage that you can invoke method references on a variable that doesn't make part of the lambda.
But note also that the number of argument that a functional interface accepts is not variable.
So you should so overload your generic method to accept different number of arguments.
For example if you want to pass one argument to the invoked method, methodApply() should have a Function<T,R> parameter :
public static <T, R> R methodApply(Function<T, R> function, T arg) {
return function.apply(arg);
}
But if you want also to to able to pass two arguments to the invoked method, methodApply() should be overloaded and have so a BiFunction<T, U, R> parameter :
public static <T, U, R> R methodApply(BiFunction<T, U, R> function, T argOne, U argTwo) {
return function.apply(argOne, argTwo);
}
If you need to pass more parameters, you can of course create your own functional interfaces : TriFunction, QuadriFunction and overload the method in the same way.
Here is a sample working code that illustrates that :
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);
}
}
Output :
methodApply() with Function
concatenated=hello world
after adding, list=[hello world]
afer removing, list=[]
methodApply() with BiFunction
substring=hello
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With