Java try/catch 方法
Java try/catch method
我是 Java 的新手,我的函数有很多 try/catch 块我想清理。我想把每个部分都放在一个单独的私有辅助方法中,并且只调用主函数中的几个函数,但是当我这样做时,我得到了一个 java.util.NoSuchElementException 扫描仪。
这里是原函数。任何帮助将不胜感激。
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;
}
}
首先,为了不得到 java.util.NoSuchElementException
,您需要使用 hasNextLine()
检查下一行是否存在。
在您的 while 循环中添加该检查:
while (!model.isGameOver() && scan.hasNextLine()) {
...
}
其次,您在此处的其他评论中获得了很好的代码样式提示,我建议您采纳它们:)
几点评论:
首先,您可以用简单的 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(及其副本)以了解封装它的方法。
我是 Java 的新手,我的函数有很多 try/catch 块我想清理。我想把每个部分都放在一个单独的私有辅助方法中,并且只调用主函数中的几个函数,但是当我这样做时,我得到了一个 java.util.NoSuchElementException 扫描仪。
这里是原函数。任何帮助将不胜感激。
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;
}
}
首先,为了不得到 java.util.NoSuchElementException
,您需要使用 hasNextLine()
检查下一行是否存在。
在您的 while 循环中添加该检查:
while (!model.isGameOver() && scan.hasNextLine()) {
...
}
其次,您在此处的其他评论中获得了很好的代码样式提示,我建议您采纳它们:)
几点评论:
首先,您可以用简单的 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(及其副本)以了解封装它的方法。