在静态主方法中尝试/捕捉内部

时间:2013-09-12 04:06:42

标签: java exception-handling while-loop try-catch inputmismatchexception

我不明白这个的逻辑。如果我运行这个代码并输入一个非字符串,如字母f,我会陷入一个无限循环输出两个println,我没有再给机会输入一个int到扫描仪...它只是一直吐出来对控制台说的话。

public static void main(String[] args) {

    Scanner scan = new Scanner(System.in);//<<<<<SCANNER HERE
    int opponents = 0;
    boolean opponentsCreated = false;
    while(opponentsCreated == false)
    {
        try
        {
            System.out.print("How many players: ");
            int tempOpponents = scan.nextInt();
            if(tempOpponents > 0)
            {
                opponents = tempOpponents;
                opponentsCreated = true;
            }   
        }
        catch(InputMismatchException notAValidInt)
        {
            System.out.println("Not valid - must be a number greater than 0 ");
        }   
    }
}

但是,如果我只是简单地将扫描器更改为在while循环内声明,那么程序突然按预期工作:

public static void main(String[] args) {

    int opponents = 0;
    boolean opponentsCreated = false;
    while(opponentsCreated == false)
    {
        Scanner scan = new Scanner(System.in);//<<<<<SCANNER HERE
        try
        {
            System.out.print("How many players: ");
            int tempOpponents = scan.nextInt();
            if(tempOpponents > 0)
            {
                opponents = tempOpponents;
                opponentsCreated = true;
            }   
        }
        catch(InputMismatchException notAValidInt)
        {
            System.out.println("Not valid - must be a number greater than 0 ");
        }   
    }
}

老实说,我只是坐在这里2个小时试图找出我的程序出了什么问题只是为了发现这是我宣布扫描仪的地方,即使在两个版本的代码中扫描仪都没有出来范围。所以现在我真的很好奇它为什么会这样工作

2 个答案:

答案 0 :(得分:1)

一个可能的问题是,当发生激活时,您可能会将行尾令牌挂起。如果你通过确保在需要时吞下行尾令牌来处理这个问题,那么你可能没问题。例如:

public static void main(String[] args) {

  Scanner scan = new Scanner(System.in);// <<<<<SCANNER HERE
  int opponents = 0;
  boolean opponentsCreated = false;
  while (opponentsCreated == false) {
     try {
        System.out.print("How many players: ");
        int tempOpponents = scan.nextInt();

        // line below corrected! 
        scan.nextLine();  // *** this might not be a bad idea either ***

        if (tempOpponents > 0) {
           opponents = tempOpponents;
           opponentsCreated = true;
        }
     } catch (InputMismatchException notAValidInt) {
        System.out.println("Not valid - must be a number greater than 0 ");
        scan.nextLine();  // ****** this is what you need here *****
     }
  }
}

顺便说一句好问题!

答案 1 :(得分:1)

添加@HovercraftFullOfEels回答:

根本原因是,在所述异常的情况下扫描仪位置不移动。因此扫描仪一次又一次地保持同样的错误输入。引用JavaDoc

  

如果翻译成功,扫描仪将超过输入   匹配。

catch(InputMismatchException notAValidInt)
{
    scan.reset();
    System.out.println("Not valid - must be a number greater than 0 "); 
    //position is still 0
    scan.next(); //position is now 1
}

要想象:

Input:                  f______________
Scanner position:       ^______________

InputMismatchException  ^______________
scan.next()             _^_____________ 

相关来源(查看来源评论):

try {
            String s = next(integerPattern());
            if (matcher.group(SIMPLE_GROUP_INDEX) == null)
                s = processIntegerToken(s);
            return Integer.parseInt(s, radix);
        } catch (NumberFormatException nfe) {
            position = matcher.start(); // don't skip bad token   
            throw new InputMismatchException(nfe.getMessage());
        }