Java Pass Method as Parameter Java Pass Method as Parameter java java

Java Pass Method as Parameter


Edit: as of Java 8, lambda expressions are a nice solution as other answers have pointed out. The answer below was written for Java 7 and earlier...


Take a look at the command pattern.

// NOTE: code not tested, but I believe this is valid java...public class CommandExample {    public interface Command     {        public void execute(Object data);    }    public class PrintCommand implements Command     {        public void execute(Object data)         {            System.out.println(data.toString());        }        }    public static void callCommand(Command command, Object data)     {        command.execute(data);    }    public static void main(String... args)     {        callCommand(new PrintCommand(), "hello world");    }}

Edit: as Pete Kirkham points out, there's another way of doing this using a Visitor. The visitor approach is a little more involved - your nodes all need to be visitor-aware with an acceptVisitor() method - but if you need to traverse a more complex object graph then it's worth examining.


In Java 8, you can now pass a method more easily using Lambda Expressions and Method References. First, some background: a functional interface is an interface that has one and only one abstract method, although it can contain any number of default methods (new in Java 8) and static methods. A lambda expression can quickly implement the abstract method, without all the unnecessary syntax needed if you don't use a lambda expression.

Without lambda expressions:

obj.aMethod(new AFunctionalInterface() {    @Override    public boolean anotherMethod(int i)    {        return i == 982    }});

With lambda expressions:

obj.aMethod(i -> i == 982);

Here is an excerpt from the Java tutorial on Lambda Expressions:

Syntax of Lambda Expressions

A lambda expression consists of the following:

  • A comma-separated list of formal parameters enclosed in parentheses. The CheckPerson.test method contains one parameter, p, which represents an instance of the Person class.

    Note: You can omit the data type of the parameters in a lambda expression. In addition, you can omit the parentheses if there is only one parameter. For example, the following lambda expression is also valid:

    p -> p.getGender() == Person.Sex.MALE     && p.getAge() >= 18    && p.getAge() <= 25
  • The arrow token, ->

  • A body, which consists of a single expression or a statement block. This example uses the following expression:

    p.getGender() == Person.Sex.MALE     && p.getAge() >= 18    && p.getAge() <= 25

    If you specify a single expression, then the Java runtime evaluates the expression and then returns its value. Alternatively, you can use a return statement:

    p -> {    return p.getGender() == Person.Sex.MALE        && p.getAge() >= 18        && p.getAge() <= 25;}

    A return statement is not an expression; in a lambda expression, you must enclose statements in braces ({}). However, you do not have to enclose a void method invocation in braces. For example, the following is a valid lambda expression:

    email -> System.out.println(email)

Note that a lambda expression looks a lot like a method declaration; you can consider lambda expressions as anonymous methods—methods without a name.


Here is how you can "pass a method" using a lambda expression:

interface I {    public void myMethod(Component component);}class A {    public void changeColor(Component component) {        // code here    }    public void changeSize(Component component) {        // code here    }}
class B {    public void setAllComponents(Component[] myComponentArray, I myMethodsInterface) {        for(Component leaf : myComponentArray) {            if(leaf instanceof Container) { // recursive call if Container                Container node = (Container)leaf;                setAllComponents(node.getComponents(), myMethodInterface);            } // end if node            myMethodsInterface.myMethod(leaf);        } // end looping through components    }}
class C {    A a = new A();    B b = new B();    public C() {        b.setAllComponents(this.getComponents(), component -> a.changeColor(component));        b.setAllComponents(this.getComponents(), component -> a.changeSize(component));    }}

Class C can be shortened even a bit further by the use of method references like so:

class C {    A a = new A();    B b = new B();    public C() {        b.setAllComponents(this.getComponents(), a::changeColor);        b.setAllComponents(this.getComponents(), a::changeSize);    }}


Since Java 8 there is a Function<T, R> interface (docs), which has method

R apply(T t);

You can use it to pass functions as parameters to other functions. T is the input type of the function, R is the return type.

In your example you need to pass a function that takes Component type as an input and returns nothing - Void. In this case Function<T, R> is not the best choice, since there is no autoboxing of Void type. The interface you are looking for is called Consumer<T> (docs) with method

void accept(T t);

It would look like this:

public void setAllComponents(Component[] myComponentArray, Consumer<Component> myMethod) {    for (Component leaf : myComponentArray) {        if (leaf instanceof Container) {             Container node = (Container) leaf;            setAllComponents(node.getComponents(), myMethod);        }         myMethod.accept(leaf);    } }

And you would call it using method references:

setAllComponents(this.getComponents(), this::changeColor);setAllComponents(this.getComponents(), this::changeSize); 

Assuming that you have defined changeColor() and changeSize() methods in the same class.


If your method happens to accept more than one parameter, you can use BiFunction<T, U, R> - T and U being types of input parameters and R being return type. There is also BiConsumer<T, U> (two arguments, no return type). Unfortunately for 3 and more input parameters, you have to create an interface by yourself. For example:

public interface Function4<A, B, C, D, R> {    R apply(A a, B b, C c, D d);}