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

Java输入验证问题:如何校验输入为Double或Integer类型

问题分析

你的代码核心问题是错误使用了Scanner的hasNext()系列方法:

  • 调用scan.nextLine()时,已经把用户输入的一行内容读取到字符串变量里了,之后调用scan.hasNext()是检查控制台是否还有新的输入,而非校验已读取的字符串是否为数字,这直接导致校验逻辑完全失效。
  • 直接调用Double.parseDouble()/Integer.parseInt()遇到非数字内容会抛出NumberFormatException,但你的catch块仅输出模糊错误,无法告知用户具体哪个输入有误。
修正方案

以下提供两种可行的实现方式:

方案1:先判断再读取(推荐)

利用Scanner的hasNextDouble()/hasNextInt()先验证输入格式,再读取对应值,避免字符串转换的麻烦:

import java.util.Scanner;

class HelloWorld {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        double monthlyDeposit = 0;
        double annualRate = 0;
        int saveMonths = 0;

        // 校验并读取每月存款金额
        System.out.println("Please enter the amount to be deposited each month: ");
        while (!scan.hasNextDouble()) {
            System.out.println("Invalid response! Please enter a number.");
            scan.next(); // 跳过无效输入
        }
        monthlyDeposit = scan.nextDouble();
        scan.nextLine(); // 清除换行符,避免影响后续输入读取

        // 校验并读取年利率
        System.out.println("Please enter the annual interest rate: ");
        while (!scan.hasNextDouble()) {
            System.out.println("Invalid response! Please enter a number.");
            scan.next();
        }
        annualRate = scan.nextDouble();
        scan.nextLine();

        // 校验并读取存款月数
        System.out.println("Please enter the month you plan to save: ");
        while (!scan.hasNextInt()) {
            System.out.println("Invalid response! Please enter an integer.");
            scan.next();
        }
        saveMonths = scan.nextInt();

        // 计算示例(可替换为实际逻辑)
        double ans = monthlyDeposit + annualRate + saveMonths;
        System.out.println(ans);

        scan.close();
    }
}

方案2:对已读取的字符串做校验

如果坚持用nextLine()读取字符串,可通过捕获异常或正则表达式校验:

方式A:捕获NumberFormatException

import java.util.Scanner;

class HelloWorld {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        double monthlyDeposit = 0;
        double annualRate = 0;
        int saveMonths = 0;
        boolean validInput = true;

        // 处理每月存款金额
        System.out.println("Please enter the amount to be deposited each month: ");
        String num1 = scan.nextLine();
        try {
            monthlyDeposit = Double.parseDouble(num1);
        } catch (NumberFormatException e) {
            System.out.println("Invalid monthly deposit! Please enter a number.");
            validInput = false;
        }

        // 处理年利率
        if (validInput) {
            System.out.println("Please enter the annual interest rate: ");
            String num2 = scan.nextLine();
            try {
                annualRate = Double.parseDouble(num2);
            } catch (NumberFormatException e) {
                System.out.println("Invalid annual interest rate! Please enter a number.");
                validInput = false;
            }
        }

        // 处理存款月数
        if (validInput) {
            System.out.println("Please enter the month you plan to save: ");
            String num3 = scan.nextLine();
            try {
                saveMonths = Integer.parseInt(num3);
            } catch (NumberFormatException e) {
                System.out.println("Invalid save months! Please enter an integer.");
                validInput = false;
            }
        }

        // 执行计算(仅当所有输入有效时)
        if (validInput) {
            double ans = monthlyDeposit + annualRate + saveMonths;
            System.out.println(ans);
        }

        scan.close();
    }
}

方式B:正则表达式校验

import java.util.Scanner;
import java.util.regex.Pattern;

class HelloWorld {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        double monthlyDeposit = 0;
        double annualRate = 0;
        int saveMonths = 0;
        boolean validInput = true;

        // 匹配整数或小数的正则
        Pattern doublePattern = Pattern.compile("^[-+]?\\d+(\\.\\d+)?$");
        // 匹配整数的正则
        Pattern intPattern = Pattern.compile("^[-+]?\\d+$");

        // 校验每月存款
        System.out.println("Please enter the amount to be deposited each month: ");
        String num1 = scan.nextLine();
        if (!doublePattern.matcher(num1).matches()) {
            System.out.println("Invalid monthly deposit! Please enter a number.");
            validInput = false;
        } else {
            monthlyDeposit = Double.parseDouble(num1);
        }

        // 校验年利率
        if (validInput) {
            System.out.println("Please enter the annual interest rate: ");
            String num2 = scan.nextLine();
            if (!doublePattern.matcher(num2).matches()) {
                System.out.println("Invalid annual interest rate! Please enter a number.");
                validInput = false;
            } else {
                annualRate = Double.parseDouble(num2);
            }
        }

        // 校验存款月数
        if (validInput) {
            System.out.println("Please enter the month you plan to save: ");
            String num3 = scan.nextLine();
            if (!intPattern.matcher(num3).matches()) {
                System.out.println("Invalid save months! Please enter an integer.");
                validInput = false;
            } else {
                saveMonths = Integer.parseInt(num3);
            }
        }

        // 执行计算(仅当所有输入有效时)
        if (validInput) {
            double ans = monthlyDeposit + annualRate + saveMonths;
            System.out.println(ans);
        }

        scan.close();
    }
}
关键注意点
  • 混用nextDouble()/nextInt()和nextLine()时,必须调用scan.nextLine()清除缓冲区的换行符,否则后续nextLine()会直接读取空字符串。
  • 针对不同输入的要求(比如存款月数必须是整数),要针对性使用校验方法。

内容的提问来源于stack exchange,提问作者Aldrin James Santos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 22:50:31