【问题标题】:scanner closed exception within main method主要方法中的扫描仪关闭异常
【发布时间】:2013-12-16 16:06:44
【问题描述】:

有人可以向我强调我的主要方法的问题吗?完成第一个选项并尝试输入另一个选项后,我收到扫描仪关闭的错误异常?

我认为我遇到的问题是我的 try catch 和 finally 块的位置,但不完全确定!谢谢!

/**
 * Scanner used for input within program
 */
public static Scanner scanner = new Scanner(System.in);

/**
 * Main method that provides user with a menu in which each number
 * represents a different task in which they can carry out
 */
public static void main(String[] args) {



int menuOption=0;
do{ 
    try {

        // Declaring var for user Input (defaulted to 0)
        menuOption = showMenu();
        switch (menuOption) {

        case 1:
            add();
            break;
        case 2:
            subtract();
            break;
        case 3:
            generateRandomNumber();
            guessRandomNumber();
            break;
        case 4: // invoke print loop method (use params here to get
                // experience!)
            break;
        case 5: // invoke print sum and average
            break;
        case 6: System.out.println("Quitting Program...");
            break;
        default:
            System.out.println("Sorry, please enter valid Option");

        }// End of switch statement

    } catch (Exception ex) {
        //flush scanner
        scanner.next();
    }

    finally {
        // Finally block ensures scanner is always closed
        scanner.close();
    }

}while(menuOption!=6);

//Exiting message
System.out.println("Thanks for using this Program...");

【问题讨论】:

  • 好吧,你在 finally 块中关闭了Scanner,所以它在第一次迭代后将无法读取......

标签: java loops try-catch java.util.scanner finally


【解决方案1】:

问题在于,在循环的第一次迭代中,您在 finally 块中关闭了扫描仪。 finally 块每次都会关闭,即使没有捕获到异常。

【讨论】:

    【解决方案2】:

    我猜你是在使用异常来处理程序流(而且包罗万象!)?别。异常非常昂贵,并且将它们用于程序流会使代码非常混乱。

    您在catch 语句中使用scanner.next():这将要求新的输入。 但是由于finally 块是在catch 之后执行的,所以你会立即关闭它。

    无论是否有异常,finally 块都会执行。本来是要清理资源的,但是你清理的太早了。

    删除 try-catch(或使其更合适)并且不要在 finally 块中关闭您的扫描仪。

    【讨论】:

      【解决方案3】:

      关闭循环外的扫描器并摆脱finally

      do {
         ...
      } while (...)
      
      scanner.close();
      

      【讨论】:

        【解决方案4】:

        现在您的控制流程如下所示

        do {
            try {
                //read from scanner
            }
            finally {
                scanner.close();
            }
        } while (menuOption != 6);
        

        但这会在第一次迭代后关闭您的扫描仪。

        您可能应该将您的 do...while() 移动到 try{...} 块内。

        try {
            do{
                //read from scanner
            }
            while (menuOption != 6);
        }
        finally {
            scanner.close();
        }
        

        这样,确保关闭扫描仪的finally 块将在循环之外。

        【讨论】:

        • 这样做是否意味着不会有catch块?
        • @RNI2013 为什么不呢?如果你需要一个,那么你可以将它放在try 块之后和finally 之前。但是在您的 catch 块中,您声称要刷新扫描仪,然后您调用 scanner.next(),它很可能不应该放在 catch 中,而是放在 try 中。
        • 所以你是说不要在代码的 catch 部分刷新扫描仪,还是应该彻底刷新扫描仪?知道我在该程序的其他刷新代码的方法中尝试捕获可能是相关的。
        • @RNI2013 我不确定flash 扫描仪是什么意思。我看到您只是在调用它的 next() 方法,该方法将读取下一个找到的单词(如果有的话)并且不会将其存储在任何地方。我看不出这种行为的目的,特别是如果它依赖于之前抛出异常。
        【解决方案5】:

        也许你得到一个异常,代码进入 catch 然后进入 finally

        托盘看你有没有进入catch块

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-05-07
          • 2017-09-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多