一、什么是 Scanner?
Scanner 是 Java 标准库中用于读取用户输入或文件数据的工具类,位于 java.util.Scanner 包。
它可以解析基本数据类型和字符串,是 Java 初学者接触最多的 IO 类。
核心作用:
- ✅ 从控制台/文件中读取文本、数字等数据
- ✅ 提供多种方法适配不同数据类型的输入
- ✅ 支持判断输入是否存在,避免程序异常
二、核心方法对比:next() vs nextLine()
这是最容易混淆的两个方法,我们先看截图里的核心区别:
1. next() 方法
- 结束条件:必须读取到有效字符后才结束,空白符(空格、Tab、回车)会被视为分隔符/结束符
- 空白处理:自动忽略有效字符前的空白,有效字符后的空白会截断输入
- 局限性:无法读取包含空格的字符串
- 典型场景:读取用户名、密码、单个单词等无空格的文本
Scanner sc = new Scanner(System.in);
System.out.print("请输入:");
String str = sc.next();
System.out.println("输入结果:" + str);
// 输入:" Hello World " → 输出:"Hello"
2. nextLine() 方法
- 结束条件:以 Enter 回车 为结束符,返回回车前的所有字符
- 空白处理:保留输入中的所有空白(包括开头、中间、结尾的空格)
- 优势:可以读取包含空格的完整句子
- 典型场景:读取地址、备注、整行文本
Scanner sc = new Scanner(System.in);
System.out.print("请输入:");
String str = sc.nextLine();
System.out.println("输入结果:" + str);
// 输入:" Hello World " → 输出:" Hello World "
三、判断类方法:hasNext() 与 hasNextLine()
这类方法用于预判输入是否存在,配合循环可以实现持续输入,避免 NoSuchElementException。
1. hasNext()
- 判断逻辑:检查输入流中是否还有下一个有效 token(token 指被空白符分隔的片段)
- 阻塞特性:如果当前没有输入,会阻塞等待用户输入,直到输入有效字符或结束流
- 对应关系:通常与 next()、nextInt()、nextFloat() 等配对使用
Scanner sc = new Scanner(System.in);
System.out.print("请输入(输入 exit 退出):");
while (sc.hasNext()) {
String str = sc.next();
if ("exit".equals(str)) break;
System.out.println("你输入了:" + str);
System.out.print("请继续输入:");
}
2. hasNextLine()
- 判断逻辑:检查输入流中是否还有下一行数据(以回车为分隔)
- 阻塞特性:如果当前没有输入,会阻塞等待用户输入一行
- 对应关系:通常与 nextLine() 配对使用
Scanner sc = new Scanner(System.in);
System.out.print("请输入一行内容:");
while (sc.hasNextLine()) {
String line = sc.nextLine();
if ("exit".equals(line)) break;
System.out.println("你输入的整行是:" + line);
System.out.print("请继续输入:");
}
四、基本数据类型输入方法
Scanner 提供了专门读取基本数据类型的方法,方便直接获取数字、布尔值等:
| nextInt() | 读取 int 类型整数 | int age = sc.nextInt(); |
| nextLong() | 读取 long 类型长整数 | long phone = sc.nextLong(); |
| nextFloat() | 读取 float 类型浮点数 | float score = sc.nextFloat(); |
| nextDouble() | 读取 double 类型双精度浮点数 | double price = sc.nextDouble(); |
| nextBoolean() | 读取 boolean 类型布尔值 | boolean isStudent = sc.nextBoolean(); |
| nextByte() | 读取 byte 类型字节 | byte b = sc.nextByte(); |
| nextShort() | 读取 short 类型短整数 | short s = sc.nextShort(); |
注意事项
- 这些方法同样以空白符为分隔符,和 next() 一样会忽略前导空白
- 如果输入格式不匹配(比如输入字母却调用 nextInt()),会抛出 InputMismatchException
- 建议配合对应的 hasNextXxx() 方法判断输入合法性:
Scanner sc = new Scanner(System.in);
System.out.print("请输入一个整数:");
if (sc.hasNextInt()) {
int num = sc.nextInt();
System.out.println("你输入的整数是:" + num);
} else {
System.out.println("输入格式错误,请输入整数!");
}
五、高频坑点与避坑指南
❌ 坑点1:next() 后直接调用 nextLine() 导致数据丢失
原因:next() 读取到有效字符后,会把后面的回车符留在输入流中,nextLine() 会直接读取这个空行。
// 错误示例
Scanner sc = new Scanner(System.in);
System.out.print("请输入姓名:");
String name = sc.next();
System.out.print("请输入地址:");
String address = sc.nextLine(); // 这里会直接读到空字符串!
System.out.println("姓名:" + name + ",地址:" + address);
// 输入:"张三" → 地址会变成空字符串
解决方案:
// 正确示例
Scanner sc = new Scanner(System.in);
System.out.print("请输入姓名:");
String name = sc.next();
sc.nextLine(); // 消耗掉残留的回车
System.out.print("请输入地址:");
String address = sc.nextLine();
System.out.println("姓名:" + name + ",地址:" + address);
❌ 坑点2:hasNext() 永远不会自动结束循环
原因:hasNext() 在控制台输入时,会一直等待用户输入,不会主动结束循环。
解决方案:
- 手动设置退出条件(比如输入 exit、quit 等关键词)
- 或者从文件读取时,文件结束会自动返回 false
// 正确示例:设置退出关键词
while (sc.hasNext()) {
String input = sc.next();
if ("exit".equalsIgnoreCase(input)) {
System.out.println("程序退出!");
break;
}
System.out.println("输入内容:" + input);
}
❌ 坑点3:输入格式不匹配导致异常
原因:调用 nextInt() 却输入了字母,会抛出 InputMismatchException。
解决方案:
- 使用 hasNextXxx() 先判断输入是否合法
- 捕获异常并提示用户重新输入
// 正确示例:带异常处理
Scanner sc = new Scanner(System.in);
System.out.print("请输入年龄:");
while (true) {
if (sc.hasNextInt()) {
int age = sc.nextInt();
System.out.println("年龄:" + age);
break;
} else {
System.out.print("输入错误,请重新输入整数:");
sc.next(); // 清空错误输入
}
}
六、完整实战示例:学生信息录入系统
import java.util.Scanner;
public class StudentInfo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("=== 学生信息录入系统 ===");
System.out.print("请输入学生姓名:");
String name = sc.nextLine();
System.out.print("请输入学生年龄:");
int age = 0;
while (true) {
if (sc.hasNextInt()) {
age = sc.nextInt();
break;
} else {
System.out.print("输入错误,请输入整数年龄:");
sc.next();
}
}
sc.nextLine(); // 消耗回车
System.out.print("请输入学生家庭住址:");
String address = sc.nextLine();
System.out.print("请输入学生成绩(保留一位小数):");
float score = 0;
while (true) {
if (sc.hasNextFloat()) {
score = sc.nextFloat();
break;
} else {
System.out.print("输入错误,请输入小数成绩:");
sc.next();
}
}
System.out.println("\\n=== 录入完成 ===");
System.out.println("姓名:" + name);
System.out.println("年龄:" + age);
System.out.println("住址:" + address);
System.out.println("成绩:" + score);
sc.close(); // 关闭资源
}
}
七、总结
核心方法速记表
| next() | 以空白为分隔,不能读空格 | 读取单个单词、用户名 |
| nextLine() | 以回车为分隔,可读空格 | 读取整行文本、地址、备注 |
| hasNext() | 判断是否有下一个 token | 配合 next()/nextInt() 循环输入 |
| hasNextLine() | 判断是否有下一行 | 配合 nextLine() 循环读取行 |
| nextInt()/nextFloat() | 读取对应基本类型 | 读取数字、成绩、价格 |
关键避坑总结
💡 小贴士:Scanner 是 Java 输入处理的基础,掌握它的用法是写出健壮程序的第一步!




