Java中Scanner类读取控制台输入需注意:next()读至空白符,nextLine()读整行并消费换行符;混用nextInt()与nextLine()易跳过输入,建议统一用nextLine()后转换,或用hasNextXxx()预判类型,useDelimiter()自定义分隔符,正则校验输入格式,并用循环实现容错重试。

Java中Scanner类是读取控制台输入最常用的方式,它不仅能按类型读取整数、浮点数、字符串等,还能结合正则表达式做精准匹配与校验,避免输入异常或格式错误。
用next()和nextLine()区分读取逻辑
next()只读取到下一个空白符(空格、Tab、换行)前的内容,不包含换行符;nextLine()则读取整行,包括空格,且会消费掉上一个输入操作留下的换行符。混用时容易跳过输入——比如先用nextInt()读数字,再用nextLine()读姓名,后者会直接返回空字符串。
- 推荐统一用nextLine()读所有输入,再用parseXXX()转换数值类型
- 若必须用nextInt()/nextDouble()等,紧随其后加一句scanner.nextLine()清空缓冲区
- 对纯字符串输入,优先选nextLine(),尤其含空格的姓名、地址等
用hasNextXxx() + nextXxx()实现安全类型读取
直接调用nextXXX()可能抛InputMismatchException。更健壮的做法是先用hasNextXxx()判断是否符合预期类型,再读取。
- hasNextInt() → nextInt():确保用户输入的是合法整数
- hasNext("\d{4}-\d{2}-\d{2}") → next():配合正则预判日期格式(如2024-05-20)
- hasNext("[a-zA-Z]+") → next():只接受纯字母姓名,拒绝数字或符号
用useDelimiter()切换分隔符,适配复杂输入格式
默认以空白符分隔,但实际输入常为逗号、竖线或自定义符号分隔。调用useDelimiter()可重设规则,让next()按需切分。
- scanner.useDelimiter(",\s*"):支持"张三, 李四,王五"这种带空格的逗号分隔
- scanner.useDelimiter("\|"):处理"123|45.6|true"这类管道分隔的混合类型数据
- 用完记得scanner.useDelimiter("\s+")恢复默认,避免影响后续输入
正则匹配校验输入内容(非仅分隔)
除了用hasNext(正则)判断格式,还可结合matches()或Pattern.matches()做二次校验,尤其适合需要完整匹配的场景(如邮箱、手机号)。
- String input = scanner.nextLine().trim();
if (input.matches("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")) { /* 合法邮箱 */ } - 避免用next()直接匹配邮箱:next("[^@]+@[^@]+\.[^@]+")可能因贪婪匹配失败,不如先读再校验清晰可靠
- 手机号示例:input.matches("1[3-9]\d{9}"),兼顾简洁与主流号段
Scanner本身不提供“重试输入”机制,实际开发中常配合while循环+条件判断实现输入容错。正则不是越复杂越好,优先覆盖常见合法格式,再逐步增强边界检查。

















