【问题标题】:Try/Catch inside While in static main methodTry/Catch inside While 在静态 main 方法中
【发布时间】:2013-09-12 04:06:41
【问题描述】:

我不明白这其中的逻辑。如果我运行此代码并输入一个非整数,例如字母 f,我会陷入输出两个 println 的无限循环,并且我没有机会再次向扫描仪输入整数……它只是不断吐出话到控制台。

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 ");
        }   
    }
}

但是,如果我只是简单地将 Scanner 更改为在 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 个小时,试图弄清楚我的程序到底出了什么问题,结果却发现这是我声明我的扫描器的位置的问题,即使在两个版本的代码中扫描器都没有出现的范围。所以现在我真的很好奇为什么它会这样工作

【问题讨论】:

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


    【解决方案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());
            }
    

    【讨论】:

      【解决方案2】:

      一个可能的问题是,当异常发生时,您可能会挂起行尾标记。如果您通过确保在需要时吞下行尾标记来处理此问题,您可能会没事。例如:

      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。此外,扫描仪的指针永远不会移动,因此它会一直处理与 int 相同的错误输入。在 catch 块中添加scan.next() 也可以解决问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-01
      • 2012-01-14
      • 1970-01-01
      • 2017-07-03
      • 2016-03-24
      • 1970-01-01
      相关资源
      最近更新 更多