daemon_headmaster daemon_headmaster - 1 month ago 4
Java Question

Why is a switch case statement unable to work with properties of an Enum?

I am writing a simple game in which I use an Enum,

CommandManager
, to store information about the possible commands and what each one does. The main purposes of this Enum is to be able to print out a menu of available commands, as well as being used to check input and performing the action related to that input. My problem lies with that second use, where I am using a switch statement to determine what the user wants to do based on their input. I'm getting a compilation error when trying to use a property of an Enum (via a getter method) as a case label. The error message provided is that
case expressions must be constant expressions
. Given that the properties of
CommandManager
are declared to be final, am I right in thinking that properties of Enums simply cannot be used in switch statements? If this is the case, why?

Simplified version of the code included below in case it's an error on my end.

Method Code:

void interpretInput() {
String command = input.getInput();
if (command.length() == 2) {
switch (command) {
case CommandManager.MAINMENU.getCommand(): goToMainMenu();
break;
case CommandManager.NEWGAME.getCommand(): startNewGame();
break;
case CommandManager.LISTGAMES.getCommand(): listSavedGames();
break;
case CommandManager.EXITGAME.getCommand(): exitGame();
break;
case CommandManager.HELPMENU.getCommand(): listAllCommands();
break;
}
}
}


Enum code:

public enum CommandManager {

NEWGAME("!n", "New game"),
MAINMENU("!m", "Go to main menu"),
EXITGAME("!q", "Exit Battleships"),
LISTGAMES("!g", "List saved games"),
HELPMENU("!h", "Open help menu"),
LOADGAME("!l", "Load a new game"),
SAVEGAME("!s", "Save current game");

private final String command;
private final String menuOption;

CommandManager(String aCommand, String anOption) {
command = aCommand;
menuOption = anOption;
}

String getCommand() {
return command;
}

String getMenuOption() {
return menuOption;
}
}

Answer

You have to use a bit different approach. You can write a static method inside your enum to convert command string into CommandManager enum:

public static CommandManager fromCommand(String command) {
    for (CommandManager commandManager : values()) {
        if (commandManager.getCommand().equals(command)) {
            return commandManager;
        }
    }
    return null; // or throw exception, whatever fits best for your code
}

Then you can invoke this method to get en enum object and use a switch statement to do whatever you want:

String command = input.getInput();
CommandManager commandManager = CommandManager.fromCommand(command);
if (commandManager != null)  {
    switch (commandManager) {
        case MAINMENU: 
            goToMainMenu();
            break;
        case NEWGAME: 
            startNewGame();
            break;
        case LISTGAMES: 
            listSavedGames();
            break;
        case EXITGAME: 
            exitGame();
            break;
        case HELPMENU: 
            listAllCommands();
            break;
        default:
            throw new IllegalArgumentException("Unknown command: " + commandManager);
    }
}
Comments