Scanner读取终端输入时nextLine()跳过是因为nextInt()等方法不消费换行符,导致nextLine()直接读取残留 返回空串;应统一用nextLine()再解析或调用nextLine()清缓冲区。

Scanner 读取终端输入时为何会跳过 nextLine()?
这是最常遇到的坑:调用 next()、nextInt() 等方法后,紧接着用 nextLine() 读取字符串,结果直接返回空行。原因在于这些方法不消费输入末尾的换行符(
),而 nextLine() 恰好以换行符为终止符,于是立刻“吃掉”残留的
并返回空串。
解决方式统一且简单:
- 所有数值/单词类读取后,加一句
scanner.nextLine()清掉缓冲区残留 - 或者统一改用
nextLine()读取所有输入,再手动解析(如用Integer.parseInt()转整数)——更安全,尤其涉及混合输入时
如何验证用户输入是否符合预期格式(比如必须是正整数)?
Scanner 本身不提供输入校验能力,nextInt() 遇到非数字会抛 InputMismatchException,但异常处理后光靠 next() 无法清理坏输入,容易陷入死循环。
推荐做法是「先读字符串,再校验转换」:
立即学习“Java免费学习笔记(深入)”;
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
- 用
nextLine()获取完整输入行 - 用正则判断格式(如
input.matches("\d+")判定纯数字) - 再用
Integer.parseInt()转换;捕获NumberFormatException处理溢出或非法字符 - 验证失败时提示错误并 不 调用任何
nextXxx(),直接 continue 下一轮循环
示例片段:
String input = scanner.nextLine().trim();
if (input.matches("\d+") && Integer.parseInt(input) > 0) {
int value = Integer.parseInt(input);
// 合法正整数
} else {
System.out.println("请输入有效的正整数");
}
Linux 终端下 Scanner 是否需要特殊配置?
不需要。Java 的 System.in 在 Linux 终端中默认就是连接到 stdin 的字节流,Scanner 对其封装无平台差异。但要注意两点实际影响:
-
Scanner默认使用系统默认编码读取字节流;若终端 locale 是 UTF-8(如大多数现代 Linux 发行版),而 Java 启动未指定-Dfile.encoding=UTF-8,中文输入可能乱码——建议显式构造new Scanner(System.in, "UTF-8") - Linux 终端支持 Ctrl+D(EOF),此时
scanner.hasNextLine()返回 false;若程序依赖持续交互,需在循环外检查该条件,避免空指针或阻塞
为什么用 Scanner 而不是 BufferedReader + parseInt?
单纯从性能或控制力看,BufferedReader 更底层、更快,也更适合高并发或超大输入。但交互式录入场景下,Scanner 的优势很实在:
- 内置分词逻辑(空格/制表/换行为默认分隔符),适合命令行参数式输入(如 “add user123 25”)
- 提供
hasNextInt()、hasNextDouble()等预检方法,可避免异常驱动流程 - 无需手动处理
IOException(除构造时),对新手更友好
不过要注意:Scanner 的正则分词和缓冲机制在极端输入下可能比 BufferedReader 多占内存,但日常终端交互完全无感。
真正容易被忽略的是:Scanner 实例不能在多个线程间共享,且一旦关闭(close()),System.in 也被关闭——后续任何输入操作都会抛 IllegalStateException。交互式程序里,通常只在程序退出前 close 一次,且确保没有其他地方再尝试读取 System.in。

















