next()和nextint()不消费换行符,导致后续nextline()读到空字符串;应加scanner.nextline()清理或统一用nextline()转换;nextint()遇非数字抛异常且卡住,需hasnextint()预判或捕获后next()清除;next()读单词,nextline()读整行;scanner关闭后不可恢复,建议全局单例。

next() 和 nextLine() 混用导致输入跳过
这是最常踩的坑:调用 next()、nextInt() 等之后立刻跟 nextLine(),后者会读到一个空字符串。原因在于这些方法不消费输入末尾的换行符(\n),而 nextLine() 正好以换行符为终止符,于是它立刻“吃掉”残留的换行,返回空。
- 场景:先读一个整数再读一行字符串,比如菜单选择后输入用户名
- 解决办法:在
nextInt()后加一句scanner.nextLine()手动清掉换行符 - 替代方案:统一用
nextLine()读所有输入,再用Integer.parseInt()等转换,更可控
nextInt() 遇到非数字输入直接抛异常
nextInt() 不做类型校验就强行解析,只要缓冲区当前 token 不是有效整数,就会抛 InputMismatchException,而且这个“坏 token”还留在缓冲区里,下次调用仍会卡住。
- 常见错误现象:输入 “abc” 后程序崩溃,再调一次
nextInt()还是崩,陷入死循环 - 正确做法:用
hasNextInt()先判断,再读;或者捕获异常后调用next()把非法 token 清出去 - 注意:
hasNextInt()只检查“下一个完整 token”,不会跳过空格或换行,但会等待用户输入(如果缓冲区为空)
next() 和 nextLine() 对空白字符的处理差异
next() 以任意空白符(空格、tab、换行)为分隔,只返回第一个单词;nextLine() 读取整行,包括中间空格,但不包含结尾换行符。
- 使用场景:
next()适合读单个标识符(如用户名、命令名);nextLine()适合读带空格的句子、路径、配置值 - 参数差异:二者都不接受分隔符自定义,不像
useDelimiter()那样可配——别指望next(",")这种写法 - 性能影响:无本质差别,但频繁切换方法会增加逻辑复杂度,容易漏清理缓冲区
Scanner 关闭后再次调用 nextXxx() 抛 IllegalStateException
一旦调用 scanner.close(),底层关联的 System.in 流就被关闭了,后续任何 nextXXX() 调用都会立即抛 IllegalStateException,且无法恢复。
立即学习“Java免费学习笔记(深入)”;
- 典型误操作:在某个工具方法里 new Scanner(System.in) → close() → 外部再想读输入就失败
- 建议:全局只用一个
Scanner实例,生命周期与程序一致;或彻底避免 close(),由 JVM 在退出时释放 - 兼容性注意:JDK 19+ 对已关闭 Scanner 的行为更严格,老代码迁移到新 JDK 时容易暴露这个问题
缓冲区状态看不见,又影响所有后续读取——这才是最麻烦的地方。










