Scanner.nextLine() 会跳过输入,因 nextInt() 等不消费换行符,导致 nextLine() 直接读取残留的 \n;应统一用 nextLine() + parseXXX() 转换,并手动校验格式、空值与范围。

Scanner.nextLine() 为什么总跳过输入
这是最常踩的坑:连续调用 nextInt() 或 nextDouble() 后紧跟 nextLine(),后者会立刻返回空字符串。因为前几个方法只读数字,不消费回车符(\n),而 nextLine() 恰好把残留的换行当成了“一行”。
实操建议:
- 统一用
nextLine()读所有输入,再用Integer.parseInt()、Double.parseDouble()转类型 —— 更可控,也避免缓冲区干扰 - 如果必须混用,每次调用
nextInt()后手动加一句scanner.nextLine()清掉换行 - 别依赖
hasNextLine()判断用户是否“还没输”,它只看缓冲区有没有行,不阻塞等待;真正要等输入,就得调nextLine()
输入校验该放在 Scanner 读取时还是之后
Scanner 本身不提供校验能力,它的职责只是“把字符流切分成 token”。校验必须由你写逻辑完成,而且得在解析后、业务使用前做。
常见错误现象:直接把 scanner.nextInt() 的结果当安全整数用,一旦用户输 “abc”,程序抛 InputMismatchException 就崩了。
实操建议:
- 永远用
nextLine()读原始字符串,再用try-catch包裹Integer.parseInt()等转换操作 - 校验逻辑要覆盖空输入(
str.trim().isEmpty())、格式错误、范围越界(比如年龄不能是 -5) - 别在循环里反复 new Scanner(System.in) —— 它内部持有一个不可重置的输入流,重复创建会导致资源泄漏或异常
怎么安全地循环读多个有效输入直到满足条件
典型场景:让用户不断输入密码,直到两次输入一致;或输入一个 1–100 的分数,不合法就重试。
关键点在于“不退出循环,也不让异常中断流程”。靠 hasNextXxx() 不可靠(它们不阻塞,且对非法输入无反应),必须结合 nextLine() + 显式解析 + 条件判断。
实操示例(读非空用户名):
String username = "";
while (username.trim().isEmpty()) {
System.out.print("请输入用户名:");
username = scanner.nextLine().trim();
if (username.isEmpty()) {
System.out.println("用户名不能为空!");
}
}
注意:scanner.hasNext() 在这里毫无意义——它可能返回 true,但接下来 next() 还是卡住等输入;不如老老实实用 nextLine() 主动取。
Scanner 关闭后还能不能继续用
不能。调用 scanner.close() 会连带关闭 System.in,后续任何对 System.in 的读取(包括新 Scanner)都会抛 NoSuchElementException 或阻塞不动。
实操建议:
- 除非明确知道整个程序不会再读控制台(比如主流程结束),否则不要 close Scanner
- 如果用 try-with-resources,务必确认这是最后一次输入操作;否则改用普通声明 + 不 close
- 多线程环境下更要小心:一个线程 close 了,其他线程的 Scanner 全废
真正麻烦的不是语法怎么写,而是缓冲区状态、异常传播路径和流生命周期这三者咬合在一起——稍不留神,控制台就“失联”了。

















