Scanner报NoSuchElementException异常原因排查求助
解决Scanner抛出NoSuchElementException的问题
这个问题的核心原因几乎可以肯定是你在viewTournaments方法里关闭了Scanner实例——而Scanner默认关联的是System.in(标准输入流),一旦你在子方法里调用了scanner.close(),不仅会关闭Scanner,还会把底层的System.in也一并关闭。当方法执行完回到主方法,再调用scanner.nextInt()时,因为输入流已经被关闭,自然就会抛出NoSuchElementException。
你提到控制台能输出正确数据,这是因为viewTournaments里的逻辑在关闭流之前已经完成了输入读取,只是流关闭后后续的读取操作就失效了。
具体解决方案:
- 不要在子方法中关闭Scanner:统一在整个程序的最后(比如主方法结束前)关闭一次Scanner即可。
- 复用同一个Scanner实例:不要在
viewTournaments里新建Scanner,而是把主方法里的Scanner作为参数传递进去,确保所有输入操作都依赖同一个关联System.in的Scanner对象。
举个例子,修改你的viewTournaments方法:
// 原来的写法(错误) public void viewTournaments() { Scanner localScanner = new Scanner(System.in); // 读取4支队伍的逻辑... localScanner.close(); // 这里关闭了System.in,坑就在这! } // 修改后的写法(正确) public void viewTournaments(Scanner sharedScanner) { // 直接使用传入的Scanner处理输入 System.out.println("请选择4支队伍:"); for (int i = 0; i < 4; i++) { int teamChoice = sharedScanner.nextInt(); // 处理队伍选择逻辑... } // 不要在这里调用close()! }
然后在主方法的case 4分支里这样调用:
// 主方法里只初始化一次Scanner Scanner mainScanner = new Scanner(System.in); // ...其他代码... case 4: viewTournaments(mainScanner); // 传递同一个Scanner实例 break; // ...其他switch分支... // 程序完全结束前再关闭Scanner mainScanner.close();
额外说明:
System.in是全局的标准输入流,一旦被关闭就无法重新打开,所有依赖它的Scanner都会彻底失效。这就是为什么你在回到第24行执行choice = scanner.nextInt();时会触发异常——此时输入流已经不存在了。
内容的提问来源于stack exchange,提问作者CasaRol
相关产品推荐
相关产品推荐

