You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中InputMismatchException失效,是否需改用Scanner替代DataInputStream?

问题分析与解决方案

首先明确回答你的问题:是的,使用Scanner确实能让你正常捕获InputMismatchException,不过我们先搞清楚当前代码出问题的根源,再给出两种可行的解决方案。

为什么当前代码捕获不到InputMismatchException?

你现在的写法里,DataInputStream.readLine()只是单纯读取控制台输入的字符串,它不会做任何类型校验,自然也不会抛出InputMismatchException——这个异常是Scanner类的专属异常,专门用于表示输入的数据类型和预期不匹配的场景。

真正抛出NumberFormatException的是Integer.parseInt()方法:当你传入像"1.2"这样的非整数字符串时,它无法将其解析为整数,就会抛出这个异常,而你的catch块写的是捕获InputMismatchException,根本抓不到这个异常,所以程序直接崩溃了。

解决方案1:改用Scanner(推荐)

用Scanner的nextInt()方法时,它会自动校验输入是否为整数,如果输入不符合要求(比如输入1.2),就会直接抛出InputMismatchException,正好匹配你想要捕获的异常类型。而且Scanner的API更适合处理控制台的交互式输入,代码逻辑也更清晰:

import java.util.Scanner;
import java.util.InputMismatchException;

public class NChooseR {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int numChosenObj = -1;
        int numTotalObj = -1;

        // 处理第一个输入的异常与循环输入
        while (true) {
            try {
                System.out.print("Enter the number of objects to choose: ");
                numChosenObj = scanner.nextInt();
                break; // 输入正确,跳出循环
            } catch (InputMismatchException e) {
                System.out.println("You must input an integer value.");
                scanner.nextLine(); // 清空输入缓冲区的无效内容,避免死循环
            }
        }

        // 处理第二个输入的异常与循环输入
        while (true) {
            try {
                System.out.print("Enter the total number of objects to choose from: ");
                numTotalObj = scanner.nextInt();
                break;
            } catch (InputMismatchException e) {
                System.out.println("You must input an integer value.");
                scanner.nextLine();
            }
        }

        int difference = numTotalObj - numChosenObj;
        int rFact = factorial(numChosenObj);
        int nFact = factorial(numTotalObj);
        int differenceFact = factorial(difference);
        int totalWaysToChoose = nFact / (rFact * differenceFact);

        System.out.println();
        System.out.println("There are " + totalWaysToChoose + " ways to choose " + numChosenObj + " objects from " + numTotalObj + " total number of objects.");
        
        scanner.close();
    }

    // 阶乘计算方法示例
    private static int factorial(int n) {
        int result = 1;
        for (int i = 2; i <= n; i++) {
            result *= i;
        }
        return result;
    }
}

这里加了while循环和scanner.nextLine()是关键:当输入错误时,必须清空缓冲区里的无效输入,否则nextInt()会一直读取同一个错误的输入,导致程序陷入无限循环。

解决方案2:不换DataInputStream,修改异常捕获

如果你不想改用Scanner,只需要把catch块的异常类型改成NumberFormatException,就能捕获输入非整数的情况了:

import java.io.DataInputStream;
import java.io.IOException;

public class NChooseR {
    public static void main(String[] args) throws IOException {
        DataInputStream input = new DataInputStream(System.in);
        int numChosenObj = -1;
        int numTotalObj = -1;

        try {
            System.out.print("Enter the number of objects to choose: ");
            numChosenObj = Integer.parseInt(input.readLine());
        } catch (NumberFormatException e) { // 修改为捕获NumberFormatException
            System.out.println("You must input an integer value.");
            // 这里可以添加逻辑让用户重新输入,否则后续计算会因非法值出错
        }

        try {
            System.out.print("Enter the total number of objects to choose from: ");
            numTotalObj = Integer.parseInt(input.readLine());
        } catch (NumberFormatException e) { // 同样修改异常类型
            System.out.println("You must input an integer value.");
        }

        // 后续计算逻辑...
        input.close();
    }

    // 阶乘计算方法...
    private static int factorial(int n) {
        int result = 1;
        for (int i = 2; i <= n; i++) {
            result *= i;
        }
        return result;
    }
}

不过这种写法需要你自己手动实现重新输入的逻辑,整体便利性不如Scanner方案。

内容的提问来源于stack exchange,提问作者gino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 12:27:48