Java Scanner调用nextLine()终端抛NoSuchElementException问题咨询
问题诱因
- 根本原因是程序运行时
System.in标准输入流已经处于EOF(结束)状态,Scanner读取不到有效行直接抛出异常。 - 常见触发场景:
- 终端运行时配置了输入重定向(如
java xxx < 空文件)或管道输入(如echo -n | java xxx),输入流没有可读取的内容直接结束。 - 代码中任意位置调用过
Scanner.close()方法,该操作会连带关闭底层的System.in流,而System.in是JVM全局单例的流,一旦关闭无法重新打开,后续所有读取输入的操作都会失败。 - 程序在非交互终端环境下运行,运行环境本身没有提供可交互的输入通道,启动时就将
System.in标记为结束状态。
- 终端运行时配置了输入重定向(如
- IntelliJ运行正常是因为其内置控制台做了特殊兼容处理,会维持输入流的等待状态,屏蔽了部分流关闭的异常场景。
修复方案
- 排查运行命令:如果是需要交互输入的场景,不要添加输入重定向、管道输入等参数,直接用
java [主类名]的方式运行。 - 避免手动关闭Scanner:全局共用同一个
Scanner实例即可,全程不要调用close()方法,程序退出时JVM会自动回收相关资源。 - 增加读取前校验:调用
nextLine()前先通过hasNextLine()判断是否有可读取的行,避免无输入时直接抛出异常。
修复后代码示例
import java.util.Scanner; public class ScannerExample { // 全局共用唯一Scanner实例,不要反复创建新实例 private static final Scanner GLOBAL_SCANNER = new Scanner(System.in); public static void main(String[] args) { System.out.print("Input: "); if (GLOBAL_SCANNER.hasNextLine()) { String input = GLOBAL_SCANNER.nextLine(); System.out.println("Output: " + input); } else { System.err.println("无可用输入,程序退出"); System.exit(1); } // 禁止调用 GLOBAL_SCANNER.close() } }
内容的提问来源于stack exchange,提问作者McXD
相关产品推荐
相关产品推荐

