
本文介绍使用 scanner 读取单行多个整数时的典型阻塞问题,指出 hasnextint() 在无后续输入时会无限等待,并推荐以 nextline() + 字符串分割为核心的安全替代方案。
本文介绍使用 scanner 读取单行多个整数时的典型阻塞问题,指出 hasnextint() 在无后续输入时会无限等待,并推荐以 nextline() + 字符串分割为核心的安全替代方案。
在 Java 控制台交互中,当用户需一次性输入多个整数(如 1081 678 873 1438 1276 1243 428)并存入集合时,许多开发者会误用 Scanner.hasNextInt() 配合循环读取。但该方法并非检测“行末”,而是检测“下一个完整 token 是否可解析为 int”——若输入流尚未关闭且无更多 token(例如用户已回车但 Scanner 仍在等待下个输入),hasNextInt() 将阻塞等待,导致程序挂起,无法继续执行后续逻辑(如调用 someMethod())。
根本原因在于:hasNextInt() 是面向 token 的前瞻判断,它不感知换行符,也不自动消耗换行缓冲;而用户直觉中的“输入结束”实际是一行文本的终结,应由 nextLine() 显式捕获。
✅ 推荐解决方案:先读整行,再解析
使用 nextLine() 安全获取用户输入的全部字符,再通过字符串分割提取数值:
case 2:
ArrayList<Integer> ciphertext = new ArrayList<>();
System.out.print("Enter the ciphertext: ");
// ✅ 安全读取整行,不阻塞
String line = input.nextLine().trim();
// ✅ 按空白字符(空格、制表符等)分割
String[] tokens = line.split("\s+");
// ✅ 逐个解析,跳过空字符串(防连续空格)
for (String token : tokens) {
if (!token.isEmpty()) {
try {
int cipher = Integer.parseInt(token);
ciphertext.add(cipher);
} catch (NumberFormatException e) {
System.err.println("Warning: '" + token + "' is not a valid integer, skipped.");
// 可选择抛出异常或静默跳过
}
}
}
someMethod(); // ✅ 此处将正常执行
break;⚠️ 注意事项:
- 务必调用 input.nextLine() 而非 input.next():后者只读取到第一个空白符前,无法获取整行;
- .trim() 和空字符串检查:避免因首尾空格或连续空格导致 "" 被误解析;
- 异常处理不可省略:用户可能意外输入字母或符号(如 1081 as 678),parseInt 抛出 NumberFormatException,应捕获并给出友好提示;
- 不要在循环中关闭 Scanner:input.close() 应置于整个交互流程结束时(如主循环外),否则后续 case 将因 Scanner 关闭而失败;
- 若需支持负数(如 -1081),当前方案天然兼容,无需额外修改。
该方案语义清晰、行为可预测、容错性强,彻底规避了 hasNextInt() 的阻塞陷阱,是控制台多整数单行输入的标准实践。
立即学习“Java免费学习笔记(深入)”;










