Java菜单流程异常:方法调用后Scanner.nextLine被跳过问题排查
问题原因
该问题是Scanner类不同输入方法混用的典型异常:
sc.next()、sc.nextInt()这类方法仅会读取输入中分隔符(默认空格、换行、制表符)之前的有效内容,不会消费输入末尾的换行符\n,执行后换行符会残留在输入缓冲区中replaceAll等方法执行时调用了两次sc.next(),方法结束后缓冲区残留了用户最后一次输入按下回车产生的换行符- 回到菜单逻辑调用
sc.nextLine()时,会直接读取到缓冲区里残留的换行符,返回空字符串,所以会出现userChoice为空、跳过用户输入步骤直接执行后续逻辑的情况 printReverse方法内没有调用任何Scanner输入方法,不存在换行符残留,所以返回菜单后可以正常等待用户输入
解决方法
可选的修复方案如下:
方案1:主动消费残留换行符
在所有调用了sc.next()、sc.nextInt()等非nextLine输入方法的位置,执行完输入逻辑后新增一行sc.nextLine(),主动吃掉缓冲区残留的换行符,以replaceAll方法为例:
public static void replaceAll(String a){ System.out.println("Enter Char"); String charToBeReplaced = sc.next(); System.out.println("New Char"); String charReplacement = sc.next(); sc.nextLine(); // 新增该行,消费输入末尾残留的换行符 userString = a.replaceAll(charToBeReplaced, charReplacement); System.out.println("Your new sentence is: " + userString); menu(); }
所有用到非nextLine输入方法的业务方法都需要做对应修改。
方案2:统一使用nextLine读取所有输入
将所有输入逻辑统一使用sc.nextLine()实现,从根源上避免两种读取方法混用的冲突,修改后replaceAll方法示例:
public static void replaceAll(String a){ System.out.println("Enter Char"); String charToBeReplaced = sc.nextLine(); System.out.println("New Char"); String charReplacement = sc.nextLine(); userString = a.replaceAll(charToBeReplaced, charReplacement); System.out.println("Your new sentence is: " + userString); menu(); }
如果需要读取数字等非字符串类型,读取到内容后自行做类型转换即可。
额外优化建议
当前菜单逻辑通过递归调用menu()实现循环,长时间高频使用可能出现栈溢出问题,建议修改为while循环结构实现菜单循环。
内容的提问来源于stack exchange,提问作者Steve R
相关产品推荐
相关产品推荐

