Java String用Scanner nextLine()赋值后匹配异常问题求助
Java控制台输入字符串匹配失败的问题排查
问题描述
我在处理控制台输入的逻辑时遇到了问题:当输入kill后,程序没有进入对应的判断分支,反而输出"Illegal Arguements given."。同时我也不确定使用s.nextLine()读取输入时是否会丢弃当前值,以及为什么字符串读取正确但下一行匹配错误。我的代码如下:
while (loop == true) { Scanner s = new Scanner(System.in); String a = s.nextLine(); String in = a; info("User input: " + in, "DEBUG", 0); if (in == "kill") { info("Are you sure you would like to kill the running instance? [Y/N]", "CONSOLE", 0); if (in == "Y" || in == "y") { info("Starting KILL method.", "CONSOLE", 0); s.close(); loop = false; } else if (in == "N" || in == "n") { info("Cancelled.", "CONSOLE", 0); } else { info("Illegal arguements given. Cancelled.", "CONSOLE", 0); } } else { info("Illegal Arguements given.", "CONSOLE", 0); } }
当输入kill时,控制台输出:
[info @ DEBUG/0]> User input: kill
[info @ CONSOLE/0]> Illegal Arguements given.
问题分析与解决方案
1. 核心错误:用==比较字符串内容
在Java里,==是用来比较对象的内存引用地址的,不是字符串的实际内容。哪怕两个字符串字面上完全一样,只要它们是不同的对象(比如你从Scanner读取的输入字符串,和代码里写的常量字符串"kill"),==都会返回false,这就是你输入kill却进入else分支的根本原因。
修复方式:用equals()方法比较字符串内容,如果要忽略大小写可以用equalsIgnoreCase():
- 判断
kill改为:in.equals("kill") - 判断Y/N改为:
confirm.equalsIgnoreCase("y")和confirm.equalsIgnoreCase("n")
2. Scanner对象的错误使用
- 你在循环里每次都新建
Scanner对象,完全没必要,而且如果在循环内关闭Scanner,会连带关闭System.in,导致后续再也读不到输入。 - 另外,当你输入
kill后,程序输出了确认提示,但你没有读取用户新输入的Y/N,直接用之前的in(值还是kill)去判断,这逻辑肯定不对,自然会进入非法参数分支。
修复方式:
- 把
Scanner的创建移到循环外面,全程只用一个实例。 - 在进入
kill分支后,调用s.nextLine()读取用户的确认输入,用新的变量存储这个值再做判断。
修复后的完整代码
Scanner s = new Scanner(System.in); // 移到循环外创建,复用同一个实例 boolean loop = true; while (loop) { String in = s.nextLine(); info("User input: " + in, "DEBUG", 0); if (in.equals("kill")) { info("Are you sure you would like to kill the running instance? [Y/N]", "CONSOLE", 0); String confirm = s.nextLine(); // 读取用户的确认输入 if (confirm.equalsIgnoreCase("y")) { info("Starting KILL method.", "CONSOLE", 0); loop = false; } else if (confirm.equalsIgnoreCase("n")) { info("Cancelled.", "CONSOLE", 0); } else { info("Illegal arguments given. Cancelled.", "CONSOLE", 0); } } else { info("Illegal Arguments given.", "CONSOLE", 0); } } s.close(); // 循环结束后再关闭Scanner
额外说明
s.nextLine()会完整读取当前输入行的所有内容(直到换行符),并自动丢弃末尾的换行符,不会丢失输入的内容,读取到的字符串是完整的用户输入。- 注意拼写错误:代码里的
arguements应该是arguments,建议统一修正。
内容的提问来源于stack exchange,提问作者thomas kirrane
相关产品推荐
相关产品推荐

