问题
The code below is one of the key methods for my simple 'maze game' program (which, despite its simplicity, happens to be my biggest project yet). In this method, I am defining the possible user commands and giving instructions for their execution. The reason I have the "throw IllegalArgumentException" at the top is that, when I call this method in the main method, I want to catch random or erroneous user input as an 'IllegalArgumentException e' and print out a message ("That's not a valid command. Enter "help" if you want to know the valid commands.").
Unfortunately, because I haven't come up with a way of grouping together the eight possible commands as the only possible arguments in this method, the illegal argument exception isn't thrown when I run the program and enter invalid input. Instead, nothing happens when I enter invalid input.
So I'm looking for a neat way of encoding within this method that the argument "action" is only allowed to be "help", "status" ... "down" (and the messy nature of the "save" command throws a spanner in the works). Any suggestions? I'm thinking that the answer might involve turning the possible commands into an array, but exactly how to do it isn't clear to me (because I'm a n00b).
public static void performAction(String action) throws IllegalArgumentException {
if (action.equalsIgnoreCase("help")) {
printHelp(); }
if (action.equalsIgnoreCase("status")) {
printStatus(); }
if (action.equalsIgnoreCase("board")) {
printBoard(); }
if (((action.charAt(0) == 'S') || (action.charAt(0) == 's')) && ((action.charAt(1) == 'a') || (action.charAt(1) == 'A')) && ((action.charAt(2) == 'v') || (action.charAt(2) == 'V')) &&
((action.charAt(3) == 'e') || (action.charAt(3) == 'E')) && (action.charAt(4) == ' ')) {
String [] parts = action.split(" ");
String saveCommand = parts[0];
String fileName = parts[1];
try { saveGame(fileName); }
catch(IOException e) {
System.err.printf("Error: Could not save the current game configuration to \'%s\'.", fileName);
return; } }
if (action.equalsIgnoreCase("left")) {
int a = getCurrentXPosition();
int b = getCurrentYPosition();
moveTo((a - 1), b); }
if (action.equalsIgnoreCase("right")) {
int a = getCurrentXPosition();
int b = getCurrentYPosition();
moveTo((a + 1), b); }
if (action.equalsIgnoreCase("up")) {
int a = getCurrentXPosition();
int b = getCurrentYPosition();
moveTo(a, (b - 1)); }
if (action.equalsIgnoreCase("down")) {
int a = getCurrentXPosition();
int b = getCurrentYPosition();
moveTo(a, (b + 1)); }
}
回答1:
I would use an enum like this.
public class Actor {
public void performAction(String actionString) throws IllegalArgumentException {
String[] words = actionString.split(" ", 2);
Action action = Action.valueOf(words[0].toUpperCase());
if (words.length == 1)
action.perform(this);
else
action.perform(this, words[1]);
}
enum Action {
HELP {
@Override
public void perform(Actor a) {
a.printHelp();
}
},
STATUS {
@Override
public void perform(Actor a) {
a.printStatus();
}
},
BOARD {
@Override
public void perform(Actor a) {
a.printBoard();
}
},
SAVE {
@Override
public void perform(Actor a, String fileName) {
try {
a.saveGame(fileName);
} catch (IOException ioe) {
System.err.printf("Error: Could not save the current game configuration to \'%s\'.", fileName);
ioe.printStackTrace();
}
}
};
public void perform(Actor a) {
System.out.println("Expected a second word");
}
public void perform(Actor a, String word) {
System.out.println("Expected one word");
}
}
来源:https://stackoverflow.com/questions/43513726/how-to-limit-the-string-arguments-that-a-method-can-use-to-a-fixed-list