Java Scanner 类详解

在 Java 编程中,Scanner类是处理用户输入的重要工具,它提供了强大而灵活的文本解析能力。本文将深入解析Scanner类的核心功能、使用场景及最佳实践,帮助开发者高效处理控制台输入、文件读取等场景。

一、Scanner 类的核心功能

Scanner类位于java.util包下,主要用于从各种输入源(如标准输入、文件、字符串等)解析基本数据类型和字符串。其核心功能包括:

  1. 基本数据类型解析:支持读取intdoubleboolean等基本类型
  2. 字符串解析:按行或按分隔符读取字符串
  3. 自定义分隔符:通过useDelimiter()方法指定分隔符
  4. 正则表达式匹配:支持使用正则表达式匹配特定模式

二、基本用法:从标准输入读取数据

1. 读取控制台输入的字符串和数字

 
import java.util.Scanner;

public class ScannerExample {
    public static void main(String[] args) {
        // 创建Scanner对象,关联标准输入流
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("请输入您的姓名: ");
        String name = scanner.nextLine();  // 读取整行文本
        
        System.out.print("请输入您的年龄: ");
        int age = scanner.nextInt();       // 读取整数
        
        System.out.print("请输入您的身高(m): ");
        double height = scanner.nextDouble();  // 读取浮点数
        
        System.out.printf("姓名: %s, 年龄: %d, 身高: %.2f\n", name, age, height);
        
        // 关闭Scanner(重要!避免资源泄漏)
        scanner.close();
    }
}

2. 关键方法说明

  • nextLine():读取一整行文本(包括换行符),返回字符串
  • next():读取下一个标记(以分隔符为界),返回字符串
  • nextInt()、**nextDouble()** 等:读取对应类型的数据,指针移至下一个标记
  • hasNext()、**hasNextInt()** 等:判断是否还有下一个标记或特定类型的数据

三、处理不同输入源

1. 从文件读取数据

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class FileReadingExample {
    public static void main(String[] args) {
        try {
            // 创建File对象指向待读取的文件
            File file = new File("data.txt");
            
            // 创建Scanner对象关联文件输入流
            Scanner scanner = new Scanner(file);
            
            // 逐行读取文件内容
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                System.out.println(line);
            }
            
            scanner.close();  // 关闭Scanner
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}
 

2. 从字符串读取数据

 
import java.util.Scanner;

public class StringParsingExample {
    public static void main(String[] args) {
        String input = "姓名:张三 年龄:25 身高:1.75";
        
        // 创建Scanner对象关联字符串
        Scanner scanner = new Scanner(input);
        
        // 设置分隔符为空格或冒号
        scanner.useDelimiter("[ :]");
        
        while (scanner.hasNext()) {
            String token = scanner.next();
            System.out.println(token);
        }
        
        scanner.close();
    }
}
 

四、高级用法:自定义分隔符与正则匹配

1. 使用正则表达式作为分隔符

import java.util.Scanner;

public class DelimiterExample {
    public static void main(String[] args) {
        String data = "Hello,World|Java-Programming";
        
        // 使用正则表达式设置多个分隔符
        Scanner scanner = new Scanner(data);
        scanner.useDelimiter("[,|\\-]");  // 逗号、竖线或连字符
        
        while (scanner.hasNext()) {
            System.out.println(scanner.next());
        }
        
        scanner.close();
    }
}
 

2. 正则表达式匹配特定模式

import java.util.Scanner;

public class RegexMatchingExample {
    public static void main(String[] args) {
        String input = "ID:1001 Name:Alice Age:25";
        
        Scanner scanner = new Scanner(input);
        
        // 匹配数字模式
        while (scanner.hasNext()) {
            if (scanner.hasNextInt()) {
                System.out.println("数字: " + scanner.nextInt());
            } else {
                System.out.println("文本: " + scanner.next());
            }
        }
        
        scanner.close();
    }
}
 

五、常见问题与解决方案

1. next () 与 nextLine () 混用导致的问题

Scanner scanner = new Scanner(System.in);

System.out.print("请输入一个数字: ");
int num = scanner.nextInt();  // 读取数字,但不读取换行符

System.out.print("请输入一行文本: ");
String line = scanner.nextLine();  // 读取残留的换行符,导致直接跳过输入

System.out.println("数字: " + num);
System.out.println("文本: " + line);

scanner.close();
 

解决方案:在nextInt()等方法后手动消耗换行符:
int num = scanner.nextInt();
scanner.nextLine();  // 消耗残留的换行符
String line = scanner.nextLine();  // 正常读取下一行
 

2. 资源泄漏问题

若不关闭Scanner,会导致底层输入流未释放,造成资源泄漏。建议使用try-with-resources语句自动关闭:
 
 
try (Scanner scanner = new Scanner(System.in)) {
    // 使用scanner读取数据
    String input = scanner.nextLine();
    System.out.println("输入: " + input);
}  // 自动关闭scanner
 

六、Scanner 类与其他输入方式的对比

方式适用场景特点
Scanner 复杂格式输入解析 灵活的分隔符设置、支持正则匹配、自动类型转换
BufferedReader 高效读取大量文本 基于字符缓冲,性能更高,但仅支持字符串读取
Console 安全读取密码等敏感信息 直接与系统控制台交互,输入密码时不显示明文
System.in 底层字节流操作 最基本的输入流,需手动处理编码和转换

七、最佳实践

  1. 及时关闭资源:使用try-with-resources确保Scanner自动关闭
  2. 注意输入缓冲:混用next()系列方法与nextLine()时,手动处理换行符
  3. 合理选择分隔符:通过useDelimiter()优化复杂格式的解析
  4. 验证输入类型:使用hasNextInt()等方法验证输入类型,避免异常
  5. 避免重复创建对象:在同一输入源的多次读取中复用Scanner实例

通过掌握Scanner类的核心功能与最佳实践,开发者可以高效处理各种输入场景,提升代码的健壮性与灵活性

posted on 2025-07-22 08:45  coding博客  阅读(401)  评论(0)    收藏  举报