12

Well I wrote some code and all I was doing was for loops, but changing which method I called. I tried using a for loop so it'd be a bit neater (and out of curiosity to see if it could be done), but it doesn't compile when I do it this way, because it doesn't recognize an item in an array as a method, I think. This is what I have:

String[] moveArray = {moveRight,moveDown,moveLeft,moveUp};
for (i = 0; i < 4; i++) {
    while (myWumpus.moveArray[i]) {
        myWumpus.moveArray[i];
        generator.updateDisplay();
    }
}

When I try compile I get

not a statement myWumpus.moveArray[i]();
';' expected myWumpus.moveArray[i]();

(It refers to the first statement in the while loop)

So, I think it's maybe because I'm making it an Array of type String? Is there a type Method? Is this at all possible? Any solutions welcome :). Also, I can get it to work using 4 while loops, so you don't need to show me that solution. Thanks!

Paul
  • 1,241
  • 5
  • 15
  • 28

5 Answers5

17

You cannot store methods directly in arrays. However you can store objects, which implement the same method differently. For example:

Mover[] moveArray = {new RightMover(), new DownMover() new LeftMover(), new UpMover() };
for (i = 0; i < 4; i++) {
    while (myWumpus.moveArray[i]) {
        moveArray[i].move();
        generator.updateDisplay();
    }
}
Avi
  • 19,313
  • 3
  • 53
  • 69
  • Very nice explanation. I'll stick to the four loops for now but if it's ever much more than that I'll try this! – Paul Jan 31 '10 at 18:19
  • A variation is uses enums. You need to pass the object operated on through a parameter in the method call, rather than the constructor. – Tom Hawtin - tackline Jan 31 '10 at 19:05
6

You can't store methods in arrays in Java, because methods aren't first-class objects in Java. It's a reason some people prefer to use other languages like Python, Scheme, etc.

The work-around is to create an interface which contains one method, then create four classes implementing that interface - the MoveRight, MoveLeft, etc... classes. Then you can store instances of those classes in your array and call them all the same way.

Claudiu
  • 206,738
  • 150
  • 445
  • 651
6

Yes, you can store methods in arrays using Reflection, however it is likely that what you actually want to do in this situation is use polymorphism.

As an example of polymorphism in relation to your problem - say you created an interface as follows:

public interface MoveCommand {
    void move();
}

You can then create implementations as follows:

public class MoveLeftCommand implements MoveCommand {
    public void move() {
        System.out.println("LEFT");
    }
}

etc. for the other move options. You could then store these in an MoveCommand[] or collection like a List<MoveCommand>, and then iterate over the array/collection calling move() on each element, for example:

public class Main {

    public static void main(String[] args) {
        List<MoveCommand> commands = new ArrayList<MoveCommand>();
        commands.add(new MoveLeftCommand());
        commands.add(new MoveRightCommand());
        commands.add(new MoveLeftCommand());

        for (MoveCommand command:commands) {
            command.move();
        }
    }

}

Polymorphism is very powerful, and the above is a very simple example of something called the Command Pattern. Enjoy the rest of your Wumpus World implementation :)

brabster
  • 39,706
  • 25
  • 137
  • 182
5

You can't call methods like that. But you can using reflection:

Just change the first line in the while-loop to:

Method m = myWumps.getClass().getMethod(moveArray[i]); // if the method is void
m.invoke(myWumps);

(you will have to declare/catch a few exceptions)

But you'd better avoid reflection, and use the Command pattern instead.

Bozho
  • 554,002
  • 136
  • 1,025
  • 1,121
  • Why it is better to avoid reflection? Is the reflection time consuming or memory overwhelming? The codes above looks very neat. – chrisTina Feb 27 '15 at 15:41
1

Updated answer for Java 8 and onwards-

Since the introduction of lambda expressions and method references in Java 8, storing various methods in variables is now possible. One main issue is that arrays don't currently support generic objects in Java, which makes storing the methods in arrays less doable. However they can be stored in other data structures like a List.

So for some simple examples you can write something like:

List<Comparator<String>> stringComparators = new ArrayList<>();
Comparator<String> comp1 = (s1, s2) -> Integer.compare(s1.length(), s2.length());
stringComparators.add(comp1);

or

List<Consumer<String>> consumers = new ArrayList<>();
Consumer<String> consumer1 = System.out::println;
consumers.add(consumer1);

and then loop/iterate through the List to get the methods.

cbender
  • 1,809
  • 1
  • 11
  • 16