You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中Scanner抛出NoSuchElementException异常的问题求助

分析与解决Scanner的NoSuchElementException问题

我来帮你拆解这个异常的成因,再给你落地的解决方法:

问题根源

你遇到的NoSuchElementException核心原因是重复关闭了标准输入流System.in,具体细节如下:

  1. 在citire方法中,你使用了try-with-resources语法创建Scanner cin——这个语法的特性就是代码块结束时自动关闭关联的资源,包括System.in流。但你还额外手动调用了cin.close();,这相当于重复关闭了一次System.in。
  2. 关键知识点: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 08:02:29