1. 引言

在Java中,Scanner类是处理输入的常用工具,尤其适合从控制台读取数据。但实际开发中经常遇到一个坑:Scanner会在缓冲区残留换行符,导致后续输入读取异常。清除Scanner缓冲区是保证输入处理稳定性的关键操作

常见问题场景: ⚠️ 使用nextInt()后直接调用nextLine(),导致nextLine()读取到空行 ⚠️ 循环输入时出现跳过输入的情况 ⚠️ 程序逻辑混乱,因为预期读取的内容被意外跳过

本文将介绍两种实用方法解决Scanner缓冲区残留问题。

2. 使用 nextLine() 和 hasNextLine() 方法

最经典的解决方案是组合使用nextLine()和hasNextLine()方法。看这个典型例子:

Scanner scanner = new Scanner("123\nHello World.");

@Test
public void givenInput_whenUsingNextLineWithHasNextLine_thenBufferCleared() {

    int number = scanner.nextInt();
    if (scanner.hasNextLine()) {
        scanner.nextLine();
    }
    String text = scanner.nextLine();

    assertEquals(123, number);
    assertEquals("Hello World", text);
}

执行流程解析:

  1. scanner.nextInt() 读取整数123,但缓冲区仍残留\n换行符
  2. hasNextLine() 检测到缓冲区有剩余内容
  3. nextLine() 主动消耗掉换行符,完成缓冲区清理
  4. 后续nextLine() 正确读取到"Hello World"

✅ 优点:逻辑清晰,兼容性好 ❌ 缺点:需要额外两行代码处理

3. 使用 skip() 方法

更简洁的方案是使用skip()方法直接跳过换行符:

@Test
public void givenInput_whenUsingSkip_thenBufferCleared() {
    int number = scanner.nextInt();
    scanner.skip("\n");
    String text = scanner.nextLine();

    assertEquals(123, number);
    assertEquals("Hello World", text);
}

核心操作:

  1. nextInt() 读取整数后
  2. skip("\n") 直接跳过缓冲区中的换行符
  3. 后续nextLine() 立即获取到有效输入

✅ 优点:单行代码解决问题,简洁高效 ⚠️ 注意:skip()参数需精确匹配换行符(Windows系统可能是\r\n

4. 总结

处理Scanner缓冲区残留是Java输入处理的基础技能,两种方案对比:

方法 代码行数 适用场景 推荐指数
nextLine()+hasNextLine() 3行 需要严格检查缓冲区 ⭐⭐⭐
skip() 1行 简单换行符清理 ⭐⭐⭐⭐

最佳实践建议

  • 优先使用skip("\n")方案,代码更简洁
  • 处理跨平台输入时,考虑使用skip("\\R?")匹配所有换行符
  • 复杂输入场景建议封装工具类,避免重复处理

完整示例代码已上传至GitHub仓库,包含更多边界情况测试用例。


原始标题:Clear the Scanner Buffer in Java | Baeldung