Scanner不能直接读取换行符后输入,因nextInt()等不消费换行符,导致nextLine()读到残留\n而返回空字符串;应统一用nextLine()读取再转换类型,并全局复用Scanner实例避免关闭System.in。

Scanner 不能直接读取换行符后的输入,多数问题出在 nextXxx() 和 nextLine() 混用导致的缓冲区残留
nextLine() 为什么经常“跳过”输入?
调用 nextInt()、nextDouble() 等方法后,它们只读取目标类型数据,但不消费其后的换行符(\n)。紧接着调用 nextLine() 会立刻读到这个残留换行符,返回空字符串。
- 典型现象:
nextInt()读年龄 →nextLine()读姓名 → 姓名为空 - 根本原因:输入流缓冲区里还躺着一个未被处理的
\n - 正确做法:在
nextInt()后加一句scanner.nextLine()清掉它
如何安全读取整行字符串(含空格)?
必须用 nextLine(),next() 只读到第一个空格或换行就停。但要注意它受前面非 nextLine() 方法影响。
- 推荐模式:统一用
nextLine()读所有输入,再手动转换类型 - 例如读整数:
int age = Integer.parseInt(scanner.nextLine().trim()) - 优点:避免缓冲区干扰;
trim()防用户多敲空格 - 缺点:需自行处理
NumberFormatException
Scanner 关闭后还能不能继续用?
不能。scanner.close() 会关闭底层的 System.in 流,之后任何读取都会抛 IllegalStateException。
立即学习“Java免费学习笔记(深入)”;
- 常见错误:在一个方法里 close,后续其他方法再 new Scanner(System.in) → 报错
- 解决方案:整个程序只创建一个
Scanner实例,全局复用,最后统一 close - 极端情况(如单元测试):改用
new Scanner(new ByteArrayInputStream("123\nabc".getBytes()))避免污染 System.in
最易忽略的是跨方法传递 Scanner 实例时的生命周期管理——很多人以为 close 是“释放 Scanner 对象”,其实它关的是输入源本身。


















