我是Java的新手,我的函数有很多我希望清理的try / catch块。我想把每个部分放在一个单独的私有帮助器方法中,只调用main函数中的一些函数,但是当我这样做时,我得到了一个java.util.NoSuchElementException for Scanner。
这是原始功能。任何帮助将不胜感激。
public void playGame(List<Card> deck, FreecellOperations<Card> model, int numCascades,
int numOpens, boolean shuffle) {
try {
Scanner scan = new Scanner(rd);
try {
Objects.requireNonNull(model);
Objects.requireNonNull(deck);
} catch (NullPointerException npe) {
throw new IllegalArgumentException("Cannot start game with null parameters.");
}
try {
model.startGame(deck, numCascades, numOpens, shuffle);
} catch (IllegalArgumentException iae) {
ap.append("Could not start game. " + iae.getMessage());
return;
}
ap.append(model.getGameState() + "\n");
while (!model.isGameOver()) {
String source = scan.next();
if (source.substring(0, 1).equals("q") || source.substring(0, 1).equals("Q")) {
ap.append("Game quit prematurely.");
return;
}
String cardIndex = scan.next();
if (cardIndex.substring(0, 1).equals("q") || cardIndex.substring(0, 1).equals("Q")) {
ap.append("Game quit prematurely.");
return;
}
String destination = scan.next();
if (destination.substring(0, 1).equals("q") || destination.substring(0, 1).equals("Q")) {
ap.append("Game quit prematurely.");
return;
}
int pileNumber = 0;
PileType sourceType = null;
boolean isValidSource = false;
while (!isValidSource) {
try {
switch (source.charAt(0)) {
case 'F':
sourceType = PileType.FOUNDATION;
pileNumber = this.validMoveCheck(source, 4);
isValidSource = true;
break;
case 'O':
sourceType = PileType.OPEN;
pileNumber = this.validMoveCheck(source, numOpens);
isValidSource = true;
break;
case 'C':
sourceType = PileType.CASCADE;
pileNumber = this.validMoveCheck(source, numCascades);
isValidSource = true;
break;
default:
throw new IllegalArgumentException();
}
} catch (IllegalArgumentException iae) {
ap.append("Invalid source pile. Try again.\n");
source = scan.next();
if (source.equals("q") || source.equals("Q")) {
ap.append("Game quit prematurely.");
return;
}
}
}
int cardNum = 0;
boolean isValidCard = false;
while (!isValidCard) {
try {
cardNum = Integer.parseInt(cardIndex);
isValidCard = true;
} catch (NumberFormatException nfe) {
ap.append("Invalid card number. Try again.\n");
cardIndex = scan.next();
if (cardIndex.equals("Q") || cardIndex.equals("q")) {
ap.append("Game quit prematurely.");
return;
}
}
}
PileType destType = null;
int destPileNum = 0;
boolean isValidDest = false;
while (!isValidDest) {
try {
switch (destination.charAt(0)) {
case 'F':
destType = PileType.FOUNDATION;
destPileNum = this.validMoveCheck(destination, 4);
isValidDest = true;
break;
case 'C':
destType = PileType.CASCADE;
destPileNum = this.validMoveCheck(destination, numCascades);
isValidDest = true;
break;
case 'O':
destType = PileType.OPEN;
destPileNum = this.validMoveCheck(destination, 4);
isValidDest = true;
break;
default:
throw new IllegalArgumentException();
}
} catch (IllegalArgumentException iae) {
ap.append("Invalid destination pile. Try again.\n");
destination = scan.next();
if (destination.equals("q") || destination.equals("Q")) {
ap.append("Game quit prematurely.");
return;
}
}
}
try {
model.move(sourceType, (pileNumber - 1), (cardNum - 1), destType, (destPileNum - 1));
ap.append(model.getGameState() + "\n");
} catch (IllegalArgumentException iae) {
ap.append("Invalid move. Try again. " + iae.getMessage() + "\n");
}
}
ap.append("Game over.");
} catch (IOException ioe) {
return;
}
}
答案 0 :(得分:3)
首先,为了不获取java.util.NoSuchElementException
,您需要使用hasNextLine()
检查下一行是否存在。
在while循环中添加该检查:
while (!model.isGameOver() && scan.hasNextLine()) {
...
}
其次,你在这里的其他评论中得到了相当不错的代码样式提示,我建议你接受它们:)
答案 1 :(得分:0)
一些评论:
首先,您可以使用简单的if
语句替换大量这些try / catch块(或完全取消它们)。
例如:
default:
throw new IllegalArgumentException();
}
} catch (IllegalArgumentException iae) {
ap.append("Invalid destination pile. Try again.\n");
destination = scan.next();
if (destination.equals("q") || destination.equals("Q")) {
ap.append("Game quit prematurely.");
return;
}
}
为什么不这样做:
default:
ap.append("Invalid destination pile. Try again.\n");
destination = scan.next();
if (destination.equals("q") || destination.equals("Q")) {
ap.append("Game quit prematurely.");
return;
}
break;
或类似的东西呢?为什么要烦恼呢?
此外,这种逻辑不正确:
cardNum = Integer.parseInt(cardIndex);
isValidCard = true;
它是一个整数的事实并不能证明它是一张有效的牌。如果有人输入5,321怎么办?显然, 是int
,但它不是真正的卡片。另外,请参阅here(及其副本)以了解封装此内容的方法。