0

0

构建健壮的Java用户输入:Scanner整数解析与异常捕获

霞舞

霞舞

发布时间:2025-09-04 16:28:18

|

722人浏览过

|

来源于php中文网

原创

构建健壮的Java用户输入:Scanner整数解析与异常捕获

本文深入探讨了Java Scanner在获取整数输入时,当用户输入非整数数据可能引发的InputMismatchException。我们将解释此异常的产生机制,并提供一种健壮的解决方案:通过结合try-catch语句有效捕获并处理该异常,从而避免程序崩溃,提升用户交互的稳定性与友好性。

1. Java Scanner整数输入面临的挑战

在使用java的java.util.scanner类获取用户整数输入时,通常会调用nextint()方法。然而,如果用户输入了非数字字符(例如字母、符号或包含空格的字符串),nextint()方法将无法成功解析,并立即抛出inputmismatchexception运行时异常,导致程序意外终止。

在初始的程序设计中,开发者可能尝试通过!sc.hasNextInt()来判断输入是否为整数,但此判断通常位于int choice = sc.nextInt();之后。这意味着,一旦nextInt()方法被调用且遇到非整数输入,异常就已经抛出,程序崩溃,!sc.hasNextInt()这行代码根本不会被执行到。

以下是导致程序崩溃的典型代码片段:

import java.util.Scanner;

public class Small_Programming_Assignment {
    public static void getSelection() {
        Scanner sc = new Scanner(System.in);
        // ... 其他输出语句 ...
        System.out.println("Enter your selection: ");
        int choice = sc.nextInt(); // 如果此处输入非整数,程序会立即崩溃,抛出InputMismatchException

        // 以下判断语句将不会被执行到
        if (!sc.hasNextInt() ) { 
            System.out.println("Invalid option. Try again.");
            getSelection();
        } 
        // ... 其他逻辑 ...
    }
    // ... 其他方法 ...
}

当用户输入非整数值时,如“abc”,程序会在执行sc.nextInt()时直接抛出InputMismatchException,导致程序终止,用户无法得到友好的错误提示。

2. 理解 InputMismatchException

InputMismatchException是java.util.InputMismatchException类的简称,它是java.util.Scanner类在尝试将输入标记(token)转换为预期类型失败时抛出的运行时异常。根据Oracle官方文档,当检索到的标记与预期类型的模式不匹配,或者标记超出预期类型的范围时,就会抛出此异常。这意味着,Scanner.nextInt()严格要求输入必须是符合整数格式的字符串。

立即学习Java免费学习笔记(深入)”;

ColorMagic
ColorMagic

AI调色板生成工具

下载

3. 健壮的整数输入处理:try-catch机制

为了有效应对InputMismatchException,避免程序崩溃,并提供友好的用户体验,我们应该采用Java的异常处理机制——try-catch语句块。try块用于包含可能抛出异常的代码,而catch块则用于捕获并处理特定类型的异常。

以下是使用try-catch改进用户选择输入逻辑的示例:

import java.util.InputMismatchException; // 导入InputMismatchException
import java.util.Scanner;

public class RobustInputExample {

    public static void main(String[] args) {
        getSelection();
        // 实际应用中可以根据需要调用其他方法
    }

    public static void getSelection() {
        Scanner sc = new Scanner(System.in); // 每次调用都创建新的Scanner实例
        int choice = 0; // 初始化选择变量

        System.out.println("\nWelcome to the Word Games program menu.");
        System.out.println("Select from one of the following options.");
        System.out.println("1. Substring problem.");
        System.out.println("2. Points problem.");
        System.out.println("3. Exit.");
        System.out.print("Enter your selection: "); // 使用print而非println,让输入紧跟提示

        try {
            choice = sc.nextInt(); // 尝试获取整数输入
        } catch (InputMismatchException e) { // 捕获InputMismatchException
            System.out.println("Invalid input. Please enter a valid number (1, 2, or 3).");
            sc.next(); // 关键步骤:清除Scanner缓冲区中的无效输入,避免下一次读取时再次遇到相同错误
            getSelection(); // 递归调用,重新获取输入
            return; // 捕获异常后,结束当前方法的执行,避免后续逻辑错误
        } finally {
            // 对于System.in的Scanner,通常不在此处关闭,因为它是一个共享资源。
            // 如果是文件或其他流的Scanner,应在此处关闭以释放资源。
        }

        // 处理有效整数输入
        if (choice == 1) {
            System.out.println("Entering Substring Problem...");
            // substringProblem(); // 实际调用对应的游戏方法
            getSelection(); // 游戏结束后返回菜单
        } else if (choice == 2) {
            System.out.println("Entering Points Problem...");
            // pointsProblem(); // 实际调用对应的游戏方法
            getSelection(); // 游戏结束后返回菜单
        } else if (choice == 3) {
            System.out.println("Goodbye!");
            System.exit(0); // 退出程序
        } else {
            System.out.println("Invalid option. Please enter 1, 2, or 3.");
            getSelection(); // 输入范围外,重新获取输入
        }
        // sc.close(); // 通常不关闭System.in的Scanner,除非程序即将退出
    }

    // 示例方法,实际应用中会包含业务逻辑
    public static void substringProblem() {
        System.out.println("Substring Problem Logic Here.");
    }

    public static void pointsProblem() {
        System.out.println("Points Problem Logic Here.");
    }
}

在上述代码中:

  1. try块包裹了sc.nextInt(),确保在尝试读取整数时能够捕获潜在的InputMismatchException。
  2. catch (InputMismatchException e)块专门用于处理非整数输入。
  3. 在catch块内部,我们首先向用户提示输入无效,并指导他们输入正确的类型。
  4. 关键步骤:sc.next()。当nextInt()失败时,无效的输入(例如“abc”)仍然留在Scanner的缓冲区中。如果不清除它,即使重新调用getSelection()并创建新的Scanner实例,这个新的Scanner仍然会从System.in的缓冲区读取到相同的无效输入,导致无限循环地抛出异常。sc.next()会读取并丢弃下一个完整的标记(token),从而清空缓冲区中的无效内容。sc.nextLine()也可以用于清除直到行尾的所有内容。
  5. 通过递归调用getSelection(),程序能够重新向用户显示菜单并等待新的有效输入。return;语句确保在异常处理后,当前getSelection()方法的剩余逻辑不会被执行。

4. 进一步优化与注意事项

  • 避免递归过深: 虽然递归调用在示例中有效,但如果用户连续输入大量无效数据,可能会导致StackOverflowError。对于用户输入循环,更推荐使用while循环结构来替代递归,以提高程序的健壮性和可维护性:

    import java.util.InputMismatchException;
    import java.util.Scanner;
    
    public class RobustInputLoopExample {
    
        public static void main(String[] args) {
            getSelectionLoop();
        }
    
        public static void getSelectionLoop() {
            Scanner sc = new Scanner(System.in); // 整个应用程序生命周期中通常只需一个Scanner实例
            int choice = 0;
            boolean validInput = false;
    
            while (!validInput) {
                System.out.println("\nWelcome to the Word Games program menu.");
                System.out.println("Select from one of the following options.");
                System.out.println("1. Substring problem.");
                System.out.println("2. Points problem.");
                System.out.println("3. Exit.");
                System.out.print("Enter your selection: ");
    
                try {
                    choice = sc.nextInt();
                    if (choice >= 1 && choice <= 3) {
                        validInput = true; // 输入有效且在范围内,跳出循环
                    } else {
                        System.out.println("Invalid option. Please enter 1, 2, or 3.");
                        // 继续循环,重新提示输入
                    }
                } catch (InputMismatchException e) {
                    System.out.println("Invalid input. Please enter a number (1, 2, or 3).");
                    sc.next(); // 清除无效输入
                    // 继续循环,重新提示输入

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

106

2023.09.25

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6607

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

842

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

1092

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

2138

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1566

2023.10.24

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
SQL 教程
SQL 教程

共61课时 | 4.3万人学习

Java 教程
Java 教程

共578课时 | 80.9万人学习

oracle知识库
oracle知识库

共0课时 | 0.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号