0

I am trying to use reflection to launch the appropriate method when the user inputs a string command. For instance, if the user inputs "go" in the terminal, the go() method of the Player class will be called by the process() method of the Command class.

However, I cannot get my code working and I get a NoSuchMethodException error that I do not know how to fix. The lines at the source of the problem are half-way through the Command class (complete classes reproduced at the bottom):

        try {
            Method method = pClass.getMethod(commandWord);
            method.invoke(player, this);
        }
        catch (NoSuchMethodException err1) {
            System.out.println("No such method");
        }

Could anyone please guide me? I thank you in advance.

LC

Command class:

import java.util.ArrayList;
import java.lang.reflect.*;

public class Command
{

    private String commandWord;
    private String secondWord;

    public Command(String firstWord, String secondWord)
    {
        commandWord = firstWord;
        this.secondWord = secondWord;
    }

    public boolean process(Player player) 
    {
        ArrayList<String> validCommands = new ArrayList<String>();
        String methodName;
        int index;

        Class pClass = player.getClass();
        Method[] methods = pClass.getDeclaredMethods();
        for (int i = 0; i < methods.length; i++) {
            if (Modifier.isPublic(methods[i].getModifiers())) {
                validCommands.add(methods[i].getName());
            }
        }

        boolean wantToQuit = false;

        if(commandWord == null) {
            System.out.println("I don't know what you mean...");
            return false;
        }

        if (commandWord.equals("help")) {
            System.out.println("You are lost. You are alone. You wander");
            System.out.println("around at the university.");
            System.out.println();
            System.out.println("Your command words are:");

            for(String command: validCommands) {
                System.out.print(command + "  ");
            }
            System.out.println();
        }
        else if (commandWord.equals("quit")) {
            wantToQuit = quit();
        }

        //THIS IS WHERE I GET THE ERROR
        try {
            Method method = pClass.getMethod(commandWord);
            method.invoke(player, this);
        }
        catch (NoSuchMethodException err1) {
            System.out.println("No such method");
        }
        catch (IllegalAccessException err2) {
            System.out.println("Illegal access");
        }
        catch (InvocationTargetException err3) {
            System.out.println("Illegal access");
        }

        return wantToQuit;
    }

    [...] //some methods omitted
}

Player class:

public class Player
{
    private String name;
    private Room currentRoom;
    private ArrayList<Item> items;

    Player (String name, Room startingRoom)
    {
        this.name = name;
        items = new ArrayList<Item>();
        this.currentRoom = startingRoom;
        printWelcome();
    }

    public void engage()
    {
        [...]
    }

    public void trade(Command command) 
    {
        [...]       }

    public void goRoom(Command command) 
    {   
        [...]       }

    public void search(Command command) 
    {
        [...]       }

    public void takeItem(Command command) 
    {
        [...]       }

    public void dropItem(Command command) 
    {
        [...]       }

    public void lock(Command command)
    {   
        [...]       }

    public void unlock(Command command)
    {   
        [...]
    }

}
2
  • I suggest adding err1.printStackTrace() to your catch block, and checking that the correct class is being referenced. That will also tell you which method it tried to call, in case something was wrong there. Commented Apr 2, 2014 at 18:31
  • Thank you Martin. I added it to my code. Commented Apr 2, 2014 at 18:41

1 Answer 1

2

Try this.

pClass.getMethod(commandWord, Command.class)

Seems to me the problem is that you're looking for methods with no
parameters while these methods all seem to have a parameter of type Command.

For more details see here:

Class.getMethod JavaDoc

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, this solved my problem. I had tried pClass.getClass().getMethod(commandWord, Command), but I got an error, that I did not know how to fix.
Yes, the thing is that there're more parameters to getMethod which tell a method with what parameters exactly you're looking for in pClass (this is useful if you have overloaded methods - same name but different list of parameters).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.