Java Scanner自定义分隔符引发异常及nextLine失效问题咨询
一、InputMismatchException异常原因
当你把Scanner的分隔符设为\n时,nextInt()会把**整行内容(包括换行符之前的所有字符)**当作一个完整的token来解析。比如在Windows环境下,输入123按回车,实际输入流是123\r\n,此时Scanner会把123\r作为一个token(因为分隔符是\n),nextInt()试图把带\r的字符串转成整数,自然触发类型不匹配的异常。
而next()只是读取到分隔符为止的字符串,它会提取123这部分有效内容,不会包含\r或\n,所以能正常返回,不会出错。
二、Scanner分隔符的工作原理
Scanner默认用**所有空白字符(空格、换行、制表符等)**作为分隔符,它会自动跳过这些空白,只提取真正的输入内容。
当你手动指定分隔符为\n后,规则完全改变:
- 输入流会被按
\n切割成一个个独立的token,每一行就是一个token - Scanner不会再忽略行内的其他空白字符(比如输入
123 456按回车,这整行会被当作一个token) - 所有读取方法(
nextInt()/next()/nextLine())都基于这些切割后的token工作,不同方法只是对token做不同类型的转换或直接返回
说白了,分隔符就是Scanner用来“切分”输入的刀,切出来的每一块就是token,后续操作都围绕这些token展开。
三、为何nextLine()无法正常工作?
nextLine()的特殊之处在于:它会直接读取从当前指针位置到下一个换行符的所有内容,包括中间的空白,并且会把这个换行符一起消费掉。
当你设置分隔符为\n后,首先nextInt()抛出异常,导致Scanner的指针停留在出错的token位置,后续调用nextLine()时,它读取的内容并不是你期望的下一行字符串,而是从当前错误位置到下一个换行符的混乱内容,自然无法正常工作。
另外,哪怕nextInt()没抛异常,nextLine()的作用也会变得冗余——因为此时每一行已经被当作一个token,next()就能直接获取整行内容,nextLine()和next()的行为会变得几乎一致,但因为分隔符设置的问题,输入流的处理逻辑已经偏离了原本的预期。
内容的提问来源于stack exchange,提问作者Anshul V. Kumar

