javainterfacemethod-reference

Java Pass Method as Parameter


I am looking for a way to pass a method by reference. I understand that Java does not pass methods as parameters, however, I would like to get an alternative.

I've been told interfaces are the alternative to passing methods as parameters but I don't understand how an interface can act as a method by reference. If I understand correctly an interface is simply an abstract set of methods that are not defined. I don't want to send an interface that needs to be defined every time because several different methods could call the same method with the same parameters.

What I would like to accomplish is something similar to this:

public void setAllComponents(Component[] myComponentArray, Method myMethod) {
    for (Component leaf : myComponentArray) {
        if (leaf instanceof Container) { //recursive call if Container
            Container node = (Container) leaf;
            setAllComponents(node.getComponents(), myMethod);
        } //end if node
        myMethod(leaf);
    } //end looping through components
}

invoked such as:

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

Solution

  • 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.