Java中Scanner抛出NoSuchElementException异常的问题求助
分析与解决Scanner的
NoSuchElementException问题 我来帮你拆解这个异常的成因,再给你落地的解决方法:
问题根源
你遇到的NoSuchElementException核心原因是重复关闭了标准输入流System.in,具体细节如下:
- 在
citire方法中,你使用了try-with-resources语法创建Scanner cin——这个语法的特性就是代码块结束时自动关闭关联的资源,包括System.in流。但你还额外手动调用了cin.close();,这相当于重复关闭了一次System.in。 - 关键知识点:
System.in是全局的标准输入流,一旦被关闭就无法重新打开。当你在marime方法里再次创建Scanner scan = new Scanner(System.in);时,这个Scanner绑定的是已经关闭的流,自然读不到任何输入,调用nextInt()就会直接抛出NoSuchElementException。
另外,你的marime方法里还有一个逻辑错误:if(i.marime <= a & i.marime >= b),这个条件几乎不会匹配任何数据(除非a和b相等),而且用按位与&而非逻辑与&&也不符合代码规范。
解决步骤
1. 全局复用Scanner,避免随意关闭System.in
不要在每个方法里单独创建并关闭Scanner,而是在main方法中创建一个全局Scanner实例,传递给需要读取输入的方法,最后在程序结束时统一关闭它。这样能保证System.in只被关闭一次,所有方法都能正常读取输入。
修改后的代码示例:
- Main方法:
public static void main(String[] args) { Scanner scanner = new Scanner(System.in); ArrayList<Aplicatie> x = citire(scanner); marime(x, scanner); scanner.close(); // 程序结束前统一关闭 }
- 修改
citire方法接收Scanner参数:
static ArrayList<Aplicatie> citire(Scanner cin) throws IOException { int n; ArrayList<Aplicatie> x = new ArrayList<Aplicatie>(); // 直接使用传入的cin读取输入,无需try-with-resources(由main管理生命周期) // 此处保留你的读取变量逻辑,比如 n = cin.nextInt(); 等操作 return x; }
- 修改
marime方法接收Scanner参数:
public static void marime(ArrayList<Aplicatie> x, Scanner scan) { System.out.println("Introdu diapazonul de marime dorit pentru a primi rezultatul"); int a = scan.nextInt(); int b = scan.nextInt(); // 不要在此处关闭scan,交给main统一处理 System.out.println("Aplicatiile cu marimea intre " + a + " si " + b + " sunt: "); for(Aplicatie i: x) { // 修复范围判断逻辑,自动适配用户输入的a、b大小 if(i.marime >= Math.min(a,b) && i.marime <= Math.max(a,b)) System.out.println(i.denumire + ' ' + i.versiune + ' ' + i.limba + ' ' + i.companieProducatoare + ' ' + i.tip + ' ' + i.cuSunet + ' ' + i.cuInstalare + ' ' + i.marime + ' ' + i.licenta); } }
2. 可选:增加输入合法性校验
为了避免用户输入非整数导致的异常,可以在调用nextInt()前先判断输入是否有效:
if(scan.hasNextInt()) { int a = scan.nextInt(); } else { System.out.println("输入不是有效的整数,请重新输入!"); scan.nextLine(); // 清空无效输入,避免死循环 }
额外建议
- 永远不要在方法内部随意关闭
System.in,它是全局资源,关闭后整个程序都无法再读取控制台输入。 - 尽量复用同一个Scanner实例,减少资源开销的同时避免流关闭问题。
内容的提问来源于stack exchange,提问作者CristiaN Fnc
相关产品推荐
相关产品推荐

