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

关闭main方法的Scanner后新建Scanner抛出NoSuchElementException问题求助

问题分析与解决方案

问题原因

当调用scanner.close()时,不仅会关闭Scanner实例,还会关闭它底层绑定的标准输入流System.in。System.in是全局唯一的输入流,一旦被关闭,整个JVM进程内无法重新打开它。后续在story方法中新建的Scanner试图从已关闭的System.in读取输入,必然抛出NoSuchElementException。

另外代码还有一个隐藏问题:nextInt()和nextDouble()只会读取数字部分,不会处理输入末尾的换行符。如果不提前消耗这个换行符,后续调用nextLine()会直接读取到空字符串,导致逻辑异常。

解决方案

方案1:复用同一个Scanner实例(推荐)

全程使用一个Scanner实例,通过参数传递给story方法,仅在程序结束时统一关闭。同时处理nextDouble()留下的换行符:

package gross_calculator;

import java.util.Scanner;

public class GrossPayCalculator {
    
    static void story(Scanner scanner) {
        System.out.println("Which season the day is of?");
        String season = scanner.nextLine();
        System.out.println("How is that day?");
        String adjective = scanner.nextLine();
        System.out.println("What is the number?");
        int number = scanner.nextInt();
        System.out.println("On a "+adjective+" "+season+" day,\nyou read "+number+" pages of book.");
    }
    
    public static void main(String[] args) {
        int hours = 0;
        System.out.println("How many hours did you work?: ");
        Scanner scanner = new Scanner(System.in);
        hours = scanner.nextInt();
        
        double payRate = 0;
        System.out.println("What is your pay rate?: ");
        payRate = scanner.nextDouble();
        
        // 消耗nextDouble留下的换行符,避免后续nextLine读空
        scanner.nextLine();
        
        double grossPay = hours*payRate;
        System.out.println("Gross pay: "+grossPay);
        
        story(scanner);
        // 程序结束前统一关闭Scanner
        scanner.close();
    }
}

方案2:不关闭关联System.in的Scanner

System.in属于JVM管理的资源,程序退出时会自动关闭,无需手动调用scanner.close()。这种方式下,即使新建Scanner也能正常读取输入,但复用Scanner更符合资源管理规范:

package gross_calculator;

import java.util.Scanner;

public class GrossPayCalculator {
    
    static void story() {
        System.out.println("Which season the day is of?");
        Scanner scanner1 = new Scanner(System.in);
        // 消耗前一个Scanner留下的换行符
        scanner1.nextLine();
        String season = scanner1.nextLine();
        System.out.println("How is that day?");
        String adjective = scanner1.nextLine();
        System.out.println("What is the number?");
        int number = scanner1.nextInt();
        System.out.println("On a "+adjective+" "+season+" day,\nyou read "+number+" pages of book.");
    }
    
    public static void main(String[] args) {
        int hours = 0;
        System.out.println("How many hours did you work?: ");
        Scanner scanner = new Scanner(System.in);
        hours = scanner.nextInt();
        
        double payRate = 0;
        System.out.println("What is your pay rate?: ");
        payRate = scanner.nextDouble();
        
        double grossPay = hours*payRate;
        System.out.println("Gross pay: "+grossPay);
        
        story();
    }
}

内容的提问来源于stack exchange,提问作者Fatih ağlar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 20:00:14