Java 输入操作详解:Scanner 类的使用与实战
Java-day08
引入
在 Java 程序开发中,输入功能是与用户交互的基础。无论是获取用户输入的数字、文本,还是处理文件数据,输入操作都不可或缺。本文将围绕 Java 中最常用的控制台输入工具——`Scanner` 类展开,从**类的导入**、**对象创建**、**基本数据类型输入**到**异常处理**,全面解析 Scanner 的使用方法,并通过实战案例帮助读者掌握 Java 输入操作的核心技能。
一、Scanner 类的引入:为什么需要导入?
Java 的类库被划分为不同的包(`package`),`Scanner` 类位于 `java.util` 包下,不属于 Java 核心包(`java.lang`),因此使用前必须通过 `import` 语句导入。
1.1 导入语法与原理
```java
import java.util.Scanner; // 导入java.util包下的Scanner类
```
- **原理**:`import` 语句告诉编译器“去哪里寻找该类的定义”,避免在代码中使用冗长的全类名(如 `java.util.Scanner scanner = new java.util.Scanner(...)`)。
- **注意事项**:
- 若需导入某个包下的所有类,可使用通配符 `*`,如 `import java.util.*;`,但不建议过度使用(可能增加编译时间);
- `java.lang` 包下的类(如 `String`、`System`)无需手动导入,编译器会自动识别。
二、Scanner 对象的创建:连接输入源
`Scanner` 类是一个“输入流扫描器”,创建对象时需指定**输入源**(如控制台、文件、字符串等),最常用的输入源是**标准输入流**(`System.in`,即控制台输入)。
2.1 基本创建语法
```java
Scanner scanner = new Scanner(System.in);
```
- **各部分含义**:
- `Scanner`:类名,指定要创建的对象类型;
- `scanner`:引用变量名,存储对象在堆内存中的地址;
- `new`:关键字,在堆内存中为对象分配空间;
- `Scanner(System.in)`:调用 Scanner 的构造方法,传入输入源 `System.in`(标准输入流,对应控制台输入)。
2.2 输入源的多样性
除了控制台,Scanner 还支持其他输入源:
```java
// 从字符串读取输入
Scanner scanner1 = new Scanner("123 abc true");
// 从文件读取输入(需处理异常,后续章节讲解)
// Scanner scanner2 = new Scanner(new File("data.txt"));
```
三、基本数据类型的输入:nextXxx() 方法详解
Scanner 提供了一系列 `nextXxx()` 方法,用于读取不同类型的输入数据,如整数、浮点数、字符串等。
3.1 读取整数:nextInt()
```java
import java.util.Scanner;
public class ScannerDemo {
public static void main(String[] args) {
// 1. 创建Scanner对象,关联控制台输入
Scanner scanner = new Scanner(System.in);
// 2. 提示用户输入
System.out.println("请输入数字:");
// 3. 读取整数(阻塞等待用户输入,直到按下回车键)
int a = scanner.nextInt();
// 4. 输出结果
System.out.println("a=" + a);
// 5. 关闭Scanner(释放资源)
scanner.close();
}
}
```
- **执行流程**:
1. 程序运行到 `scanner.nextInt()` 时会**阻塞**,等待用户输入;
2. 用户输入数字并按下回车键后,输入的字符串会被转换为 `int` 类型;
3. 转换成功后,将值赋给变量 `a`,程序继续执行。
3.2 其他常用数据类型的读取方法
| 方法名 | 功能描述 | 示例输入 |
|---|---|---|
nextByte() | 读取字节型数据(-128~127) | 100 |
nextShort() | 读取短整型数据(-32768~32767) | 1000 |
nextInt() | 读取整型数据(-2^31~2^31-1) | 123456 |
nextLong() | 读取长整型数据(-2^63~2^63-1) | 123456789012L |
nextFloat() | 读取单精度浮点型数据 | 3.14f |
nextDouble() | 读取双精度浮点型数据 | 3.1415926 |
nextBoolean() | 读取布尔型数据(true/false) | true |
next() | 读取字符串(以空白符为分隔符) | hello |
nextLine() | 读取一整行字符串(以回车键为结束) | hello world |
**代码示例**:
```java
import java.util.Scanner;
public class ScannerMultiType {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入姓名:");
String name = scanner.next(); // 读取字符串(遇空格停止)
System.out.print("请输入年龄:");
int age = scanner.nextInt(); // 读取整数
System.out.print("请输入身高(米):");
double height = scanner.nextDouble(); // 读取双精度浮点数
System.out.println("姓名:" + name + ",年龄:" + age + ",身高:" + height);
scanner.close();
}
}
```
3.3 `next()` 与 `nextLine()` 的区别
- `next()`:
- 只读取到空白符(空格、制表符、回车键)为止;
- 自动跳过输入前的空白符;
- 输入有效字符后才会处理空白符(视为分隔符)。
- `nextLine()`:
- 读取到回车键为止(包含所有空白符);
- 可读取一整行内容,包括空格。
**对比示例**:
```java
import java.util.Scanner;
public class NextVsNextLine {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("使用next()输入:");
String s1 = scanner.next(); // 输入"hello world",只读取"hello"
System.out.print("使用nextLine()输入:");
scanner.nextLine(); // 清空缓冲区的残留换行符
String s2 = scanner.nextLine(); // 输入"hello world",读取完整内容
System.out.println("s1 = " + s1); // 输出:s1 = hello
System.out.println("s2 = " + s2); // 输出:s2 = hello world
scanner.close();
}
}
```
- **注意**:`nextInt()` 等方法读取数据后,回车键会残留在输入缓冲区,若后续直接使用 `nextLine()`,会读取到空字符串,需先用 `nextLine()` 清空缓冲区。
四、输入异常处理:避免程序崩溃
当用户输入的数据类型与 `nextXxx()` 方法预期的类型不匹配时(如用 `nextInt()` 读取 "abc"),会抛出 `InputMismatchException` 异常,导致程序崩溃。因此,实际开发中需进行异常处理。
4.1 使用 `hasNextXxx()` 方法预判
`Scanner` 提供了 `hasNextXxx()` 系列方法,用于判断输入是否符合目标类型,返回 `true` 表示可以安全读取。
**代码示例**:
```java
import java.util.Scanner;
public class ScannerException {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入整数:");
// 先判断输入是否为整数
if (scanner.hasNextInt()) {
int num = scanner.nextInt();
System.out.println("你输入的整数是:" + num);
} else {
System.out.println("输入错误,不是整数!");
}
scanner.close();
}
}
```
4.2 循环读取直到输入正确
结合循环与 `hasNextXxx()`,可实现“直到输入正确才继续”的逻辑:
```java
import java.util.Scanner;
public class ScannerLoop {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int age = 0;
// 循环读取,直到输入正确的整数
while (true) {
System.out.print("请输入年龄(整数):");
if (scanner.hasNextInt()) {
age = scanner.nextInt();
break; // 输入正确,跳出循环
} else {
System.out.println("输入错误,请重新输入!");
scanner.next(); // 清空错误输入
}
}
System.out.println("你的年龄是:" + age);
scanner.close();
}
}
```
五、Scanner 的关闭:释放资源
使用完 Scanner 后,需调用 `close()` 方法释放关联的输入流资源,避免资源泄漏:
```java
scanner.close();
```
- **注意**:`System.in` 是一个全局输入流,关闭 Scanner 后,其他依赖 `System.in` 的输入操作将无法使用,因此在单程序中建议只创建一个 Scanner 对象并在最后关闭。
六、实战案例:用户信息录入系统
综合运用 Scanner 的各项功能,实现一个简单的用户信息录入系统:
```java
import java.util.Scanner;
public class UserInputSystem {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 录入姓名
System.out.print("请输入姓名:");
String name = scanner.next();
// 录入年龄(确保输入整数)
int age = 0;
while (true) {
System.out.print("请输入年龄:");
if (scanner.hasNextInt()) {
age = scanner.nextInt();
if (age > 0 && age < 150) { // 简单校验年龄合理性
break;
} else {
System.out.println("年龄需在1-149之间,请重新输入!");
}
} else {
System.out.println("年龄必须是整数,请重新输入!");
scanner.next(); // 清空错误输入
}
}
// 录入体重(确保输入浮点数)
double weight = 0.0;
while (true) {
System.out.print("请输入体重(kg):");
if (scanner.hasNextDouble()) {
weight = scanner.nextDouble();
if (weight > 0 && weight < 300) { // 简单校验体重合理性
break;
} else {
System.out.println("体重需在0-300之间,请重新输入!");
}
} else {
System.out.println("体重必须是数字,请重新输入!");
scanner.next(); // 清空错误输入
}
}
// 输出录入结果
System.out.println("\n===== 用户信息 =====");
System.out.println("姓名:" + name);
System.out.println("年龄:" + age + "岁");
System.out.println("体重:" + weight + "kg");
scanner.close();
}
}
```
七、总结:Scanner 类的核心要点
1. 导入与创建:
- 需导入 `java.util.Scanner`;
- 通过 `new Scanner(System.in)` 创建控制台输入对象。
2. 数据读取:
- 基本类型用 `nextInt()`、`nextDouble()` 等方法;
- 字符串用 `next()`(遇空格停止)或 `nextLine()`(读整行)。
3. 异常预防:
- 用 `hasNextXxx()` 预判输入类型,避免 `InputMismatchException`;
- 循环读取并校验,确保输入符合业务规则。
4. 资源管理:
- 使用完毕调用 `scanner.close()` 释放资源;
- 单程序中建议共享一个 Scanner 对象。
通过本文的学习,相信你已掌握 Scanner 类的基本使用与实战技巧。输入操作是 Java 交互程序的基础,后续学习文件 IO、网络编程时,输入流的处理思想也与此相通。建议多动手实践,结合条件判断和循环,设计更健壮的输入逻辑,为开发交互式应用打下坚实基础。
更多推荐


所有评论(0)