Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invoke Instance Method Reference On Instance Argument

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);
}
like image 871
John Smith Avatar asked Feb 27 '26 18:02

John Smith


1 Answers

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

like image 100
davidxxx Avatar answered Mar 01 '26 08:03

davidxxx



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!