找回密码
 立即注册
首页 业界区 业界 从底层逻辑,谈谈next()和nextLine()配合使用时,出现的 ...

从底层逻辑,谈谈next()和nextLine()配合使用时,出现的“跳过输入”的现象

志灿隐 2025-8-21 11:05:33
点击查看代码
  1. package com.jia.scanner;
  2. import java.util.Scanner;
  3. public class Demo01 {
  4.     public static void main(String[] args) {
  5.         //创建一个扫描器对象,用于接受键盘数据
  6.         Scanner sc = new Scanner(System.in);
  7.         System.out.println("使用next方式接受:");
  8.         //判断用户有没有输入字符串
  9.         if (sc.hasNext()){
  10.             //使用next方式接受
  11.             String str = sc.next();
  12.             System.out.println("输出的内容:" + str);
  13.         }
  14.         System.out.println("============================================");
  15.         System.out.println("使用nextLine:");
  16.         if (sc.hasNextLine()){
  17.             String str = sc.nextLine();
  18.             System.out.println("输出的内容:" + str);
  19.         }
  20.         //凡是属于IO流的类,如果不关闭会一直占用资源,要养成习惯用完就关掉
  21.         sc.close();//为了节省资源
  22.     }
  23. }
复制代码
这段代码,运行后输出的结果是:
1.png

会出现跳过用户输入的现象。但是,并不符合我的需求,我希望是在使用nextLine前,可以再次从键盘输入新的内容,再输出新的结果。
接下来,我们可以从输入缓冲区机制和next还有nextLine两种方法的底层处理逻辑进行分析,该现象产生的原因:

  • 数据是在输入缓冲区作为“中间站”暂存
    计算机在处理键盘输入时,并不是让程序直接“实时”的读取每一个按键,这样效率太低了,而是通过输入缓冲区作为中间层:

    • 用户敲击键盘的字符会先存入缓冲区,直到用户按下回车键(\n),缓冲区才会通知程序“有数据可以读取”
    • 程序中的Scanner类本质就是从缓冲区中读取数据,而不是直接从键盘读取

  • next()方法的底层处理逻辑:
    next()的核心逻辑是以空白字符为分隔符的非空白字符串读取,具体步骤是:

    • 跳过前导空白字符:自动忽略缓冲区中开头的所有空白字符(空格、指标符\t、换行符\n等)。
    • 读取有效的字符:从第一个非空白字符开始读取,持续读取直到遇到下一个空白字符(空格、换行等)。
    • 终止但是不消耗分隔符:当遇到空白字符时,next()会停止读取数据,但是这个空白字符不会被从缓冲区中移除,仍然留在缓冲区中。

  • nextLine()方法的底层处理逻辑:
    nextLine()的核心逻辑是读取一整行内容,知道换行符为止,具体步骤是:

    • 从当前位置开始读取数据:不跳过任何字符,直接从缓冲区当前位置开始读取数据。
    • 以换行符为终止符:持续读取所有字符(包括空白字符),直到遇到\n(换行符)。
    • 消耗终止符:读取完成后,会将终止的\n(换行符)从缓冲区中移除(即“消耗”掉)。
      举例:
      用户输入“hello world\n”(\n是用户按回车键产生的换行符),计算机缓冲区的内容为“hello world\n”。
      next()执行后:



  • 读取到“hello”  (非空白字符开始,知道空格停止);
  • 缓冲区中剩余“ world\n”  (空格和后续字符未被消耗移除);
    nextLine()执行后:
  • 读取到“ world”  (从当前位置,即空格开始,知道\n换行符为止);
  • 同时消耗掉\n(换行符),缓冲区变为空。
    综上所述,出现跳过输入现象的根本原因是:

  • next()读取后,缓冲区中残留了未被消耗掉的空白字符(如空格)和换行符前的字符内容;
  • 后续的nextLine()读取时,会直接从缓冲区这些残留的内容(从空白字符到\n),并消耗掉\n(换行符);
  • 由于执行完next()读取都,缓冲区还有内容(从空白字符到\n)未被消耗,所以,nextLine()无需等待用户输入新内容,导致,看起来出现了“跳过输入现象”。
    当然,存在解决方法,只需在next()后额外调用一次nextLine()清空缓冲区,即可。
    本质是:
    让第一次nextLine()消耗掉next()残留的空白字符和\n,使缓冲区为空。这样,后续真正需要使用nextLine()就会等待用户输入新内容(因为缓冲区已经被清空,必须等待新的\n触发)。
点击查看代码
  1. package com.jia.scanner;
  2. import java.util.Scanner;
  3. public class Demo01 {
  4.     public static void main(String[] args) {
  5.         //创建一个扫描器对象,用于接受键盘数据
  6.         Scanner sc = new Scanner(System.in);
  7.         System.out.println("使用next方式接受:");
  8.         //判断用户有没有输入字符串
  9.         if (sc.hasNext()){
  10.             //使用next方式接受
  11.             String str = sc.next();
  12.             sc.nextLine();//紧跟着,使用nextLine释放空格,程序才会接着让用户输入
  13.             System.out.println("输出的内容:" + str);
  14.         }
  15.         System.out.println("============================================");
  16.         System.out.println("使用nextLine:");
  17.         if (sc.hasNextLine()){
  18.             String str = sc.nextLine();
  19.             System.out.println("输出的内容:" + str);
  20.         }
  21.         //凡是属于IO流的类,如果不关闭会一直占用资源,要养成习惯用完就关掉
  22.         sc.close();//为了节省资源
  23.     }
  24. }
复制代码
该代码运行结果如下:
2.png

符合我的需求!

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册