繁体   English   中英

为什么我会收到此代码的 NoSuchElementException? Java给用户第二次正确输入机会的方法

[英]Why am I getting NoSuchElementException for this code? Java method for giving users a second chance for correct input

我正在编写一个程序,但我的代码遇到了一些问题。 我调用了一个名为secondChance()的方法,它为用户提供了第二次输入有效输入的机会。 该方法定义如下:

    Scanner input2 = new Scanner(System.in);
    StringBuilder html = new StringBuilder();
    String val;

 try {
      System.out.println("Please enter file name you would like to view (include .csv at the end):");
      String fileName = input2.nextLine(); //LINE 191

      if (!(fileName.equals("doctorList.csv"))) {
        input2.close();
        throw new FileNotFoundException();
      } else {

        BufferedReader br = new BufferedReader(new FileReader(file2));
        while ((val = br.readLine()) != null) {
          html.append(val);
        }
        br.close();
        input2.close();
        String output = html.toString();
        System.out.println(output);
      }
    } catch (FileNotFoundException e) {
      System.out.println("Invalid file input. Terminating program.");
      System.exit(0);
    } catch (IOException e) {
      System.out.println("Error occured. Terminating program.");
      input2.close();
      System.exit(0);
    }

  }

我得到的输出/错误是:

Please enter file name you would like to view (include .csv at the end):
Exception in thread "main" java.util.NoSuchElementException: No line found
        at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
        at CSV2HTML.secondChance(CSV2HTML.java:191)
        at CSV2HTML.main(CSV2HTML.java:68)

异常中的第 68 行是调用该方法的行。 请求用户输入的方法中的代码与 secondChance() 方法中显示的代码相同。 作为参考,下面是调用 secondChance() 方法的代码:

} catch (FileNotFoundException e) {
      System.out.println("Invalid file input. Now initiating second chance.");
      secondChance(); //THIS IS LINE 68
    }

编辑:我在代码块的顶部添加了 input2,以显示它的初始化位置/方式。

scanner.nextLine()抛出异常只有两种解释。 从你写问题的方式来看,这两个中只有一个在这里是可行的:

你有close() d System.in!

System.in 是您的应用程序标准输入。 假设您刚刚正常启动应用程序,那将是“键盘”,实际上是无穷无尽的,因此通常不会发生异常。 如果你用java -jar yourapp.jar <somefile.txt启动它,你是在告诉操作系统使用somefile.txt作为“键盘”,这肯定用完行,这是另一个不太可能的解释。 (如果你真的以这种方式启动你的应用程序,那么这就是你的解释:扫描器消耗了所有行。你的代码中可能存在错误导致读取“太多”行,使用调试器逐步完成)。

但是,您可以关闭此资源,这意味着任何进一步的读取 System.in 的尝试都会像您所看到的那样失败。 解决方案很简单:永远不要关闭System.in

扫描器是一个过滤器,如果您关闭扫描器,则扫描器会关闭底层资源。 因此,假设您有 System.in ( new Scanner(System.in) ) 的扫描仪,规则“不关闭 System.in”扩展为:“...并且也永远不要关闭那些扫描仪”。

你要么写过:

scanner.close();

或者你写过:

try (Scanner s = new Scanner(System.in)) {
  // stuff with scanner here
}

当代码“退出”try 块时,该构造会调用 try 括号中事物的close()方法,而不管它是如何退出的(控制流,例如return语句、抛出的异常,或者只是运行到它的结尾)。

某些 IDE 会注意到您正在使用标记为资源的 class(或者甚至是任何可以在上面的 try-with 中使用的东西),并会警告您应该使用 try-with。 编辑器/linting 工具是错误的,你必须忽略它 “哪些东西应该关闭或不应该关闭”的概念比这些简单工具的实际操作要复杂得多。 这是您实际上不能关闭的资源之一。

摆脱它。 删除scanner.close() / 替换:

try (Scanner s = new Scanner(System.in)) {
  codeHere();
}

只有:

Scanner s = new Scanner(System.in);
codeHere();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM