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/falsetrue
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、网络编程时,输入流的处理思想也与此相通。建议多动手实践,结合条件判断和循环,设计更健壮的输入逻辑,为开发交互式应用打下坚实基础。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐