Java try / catch方法

时间:2017-05-24 15:41:30

标签: java try-catch abstract-class abstract

我是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;
}
}

2 个答案:

答案 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(及其副本)以了解封装此内容的方法。