scanner.nextline()常跳过输入是因为nextint()等不消费换行符,导致nextline()读到残留\n而返回空字符串;解决方法是在nextint()后加nextline()清缓冲区,或统一用nextline()再解析。

Scanner.nextLine() 为什么经常“跳过”输入
因为 nextLine() 会读取换行符,而 nextInt()、nextDouble() 等方法不消费它,导致后续 nextLine() 立刻读到残留的 \n,返回空字符串。
- 典型现象:输入数字后调用
nextLine(),控制台没等你敲回车就直接往下走了 - 解决办法:在
nextInt()后加一句scanner.nextLine()清掉缓冲区里的换行符 - 更稳妥的做法是统一用
nextLine()读所有输入,再手动解析类型,比如Integer.parseInt(scanner.nextLine()) - 注意
hasNextLine()和hasNext()行为不同——前者只看是否有下一行,后者会阻塞等待非空白字符
Scanner 的资源泄漏风险在哪
Scanner 包装了底层输入流(如 System.in),但不会自动关闭;如果在 try-with-resources 外直接 new 出来又不 close,虽然 System.in 不会真被关掉,但可能掩盖真实资源管理问题,且违反 API 使用契约。
- 别写
new Scanner(System.in)后放任不管——尤其在方法内多次创建时 - 如果扫描的是文件(
new Scanner(new File("a.txt"))),必须close(),否则文件句柄泄露 - 对
System.in,一般不 close;但若封装成工具方法,建议文档注明“不负责关闭传入的流” - 用 try-with-resources 仅适用于可关闭的源,
System.in是个特例,强行 close 会抛IllegalStateException
中文输入乱码或卡住怎么办
根本原因是 Scanner 默认使用平台编码读取字节流,而终端(如 Windows cmd)和 IDE(如 IntelliJ 的 Terminal)编码常不一致,导致字节解码失败。
- Windows 命令行默认 GBK,但 Java 源文件通常是 UTF-8,
Scanner按系统默认解码就会错 - 解决方案:显式指定编码,如
new Scanner(System.in, "UTF-8")(前提是终端本身也设为 UTF-8) - IntelliJ 用户需同步设置:File → Settings → Editor → File Encodings → 设置 Project Encoding 和 Default encoding for properties files 为 UTF-8,并勾选 “Transparent native-to-ascii conversion”
- macOS/Linux 终端通常没问题,但若用
cat file.txt | java Main方式输入,也要确保文件编码与 Scanner 指定的一致
Scanner 在循环中反复调用 nextXxx() 的边界陷阱
每次调用 nextXXX() 都依赖内部指针推进,一旦输入不匹配预期格式(比如要 int 却输了个字母),指针不动,下次调用还会卡在同一位置,形成死循环。
立即学习“Java免费学习笔记(深入)”;
- 错误现象:输入 “abc” 后调用
nextInt(),程序卡住不动,再输什么都无效 - 必须配合
hasNextXXX()预检,例如if (scanner.hasNextInt()) { n = scanner.nextInt(); } - 如果校验失败,得用
scanner.next()消费掉非法 token,否则指针永远停在那 - 注意
hasNext()不会阻塞,但next()会——所以先判再取,顺序不能反
最麻烦的不是语法写不对,而是输入流状态和编码这两层隐式依赖——它们不报错,只让行为飘忽不定。调试时多打一行 System.out.println("read: [" + input + "]");,比翻文档快得多。











