最容易举例说明:
String test = "salut ð\u009F\u0098\u0085 test";
Scanner scan = new Scanner(test);
System.out.println("1:" + scan.nextLine());
System.out.println("2:" + scan.nextLine());
[这是用户输入中的一个字符串,所以很遗憾,我不确定100%的unicode是什么,但是如果我没记错的话,那是一个表情符号(发送时我看到了消息)。
输出为:
1:salut ð
2: test
我的预期输出仅为1行(即示例代码应给出NoSuchElementException
,因为第二个nextLine()
应该失败。)为什么将其解析为两行?什么是可能的解决方法?
当我在文本编辑器中打开文件时,它不会正确地将该Unicode视为新行。
为什么将其解析为两行?
尽管这是一个不常见的代码点,但U + 0085的Unicode名称是下一行[NEL],我想它可以被认为是换行符。
但是有没有原因
BufferedReader
和Sublime Text这样的文本编辑器没有将其解析为实际的新行,而Scanner
却将其解析为实际的新行呢?
如果您查看Scanner
和BufferedReader
的相应文档:
使该扫描仪前进到当前行之后,并返回跳过的输入。此方法返回当前行的其余部分,但不包括末尾的任何行分隔符。该位置设置为下一行的开头。
由于此方法继续在输入中搜索以寻找行分隔符 ...
Scanner.nextLine
:
读取一行文本。 行被认为由换行符('\ n'),回车符('\ r')或回车符后立即换行符中的任何一个终止。
BufferedReader.readLine
只是用模糊的术语表示“行分隔符”(它当然不是指只有一个代码点的Unicode类别“行分隔符”),而BufferedReader.readLine
文档则确切说明了什么是行。
考虑到Scanner.nextLine
还如何处理本地化的数字格式和内容,我的猜测是,它被设计为比BufferedReader.readLine
更“智能”的类。
查看我的JDK版本的源代码,Scanner
将以下字符串视为“行分隔符”:
BufferedReader
Scanner
\r\n
\n
\r
\u2028
\u2029