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
相关产品推荐
相关产品推荐

