
本文详解如何通过输入验证与循环重试机制,确保 scanner 仅接收合法整数;当用户输入非数字内容时,自动触发错误处理逻辑(如 `else` 或等效分支),避免程序崩溃,并引导用户重新输入。
在 Java 中,直接使用 Scanner.nextInt() 读取整数看似简洁,但一旦用户输入非数字字符(如 "abc"、"5.2" 或空格),会抛出 InputMismatchException,导致程序中断——此时 else 分支根本不会执行。真正可靠的方案是先以字符串形式读取全部输入,再进行格式与范围双重校验,仅在校验通过后才解析为 int。
以下是一个健壮、生产就绪的实现:
import java.util.Scanner;
public class SafeIntegerInput {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String rawInput = "";
// 循环直到获得有效整数输入
while (rawInput.isEmpty()) {
System.out.print("Enter a number to compare with 5 (q to quit): -> ");
rawInput = input.nextLine().trim();
// 支持退出指令
if (rawInput.equalsIgnoreCase("q")) {
System.out.println("Quitting - Bye Bye");
return;
}
// 正则校验:是否为带可选负号的纯数字(如 "-123", "0", "456")
// 并额外检查是否在 int 取值范围内(避免 Integer.parseInt 溢出)
if (!rawInput.matches("-?\\d+") ||
Long.parseLong(rawInput) < Integer.MIN_VALUE ||
Long.parseLong(rawInput) > Integer.MAX_VALUE) {
System.out.printf("Invalid numerical entry: \"%s\". Please enter a valid integer.%n", rawInput);
rawInput = ""; // 清空,强制重试
continue;
}
}
// ✅ 此时 rawInput 必为合法 int 字符串,安全解析
int a = Integer.parseInt(rawInput);
// 执行业务逻辑:三路比较(等于、小于、大于),无需 else 处理非法输入
if (a == 5) {
System.out.println("You have entered the same value.");
} else if (a < 5) {
System.out.println("Your number is smaller than 5.");
} else { // a > 5 —— 此 else 是逻辑完备的最终分支,非错误兜底
System.out.println("You have entered a number greater than 5.");
}
}
}✅ 关键设计说明:
- 不依赖 hasNextInt():该方法在输入流中残留分隔符(如换行符)时易引发阻塞或逻辑混乱,字符串校验更可控;
- 正则 -?\\d+ 精确匹配整数:支持负数,排除小数点、字母、空字符串;
- Long.parseLong() 辅助范围检查:防止 Integer.parseInt() 对超大数值(如 "2147483648")抛出 NumberFormatException;
- else 的语义清晰化:在输入已严格验证的前提下,else 仅代表 a > 5 这一确定逻辑分支,而非“兜底错误处理”,大幅提升代码可读性与可维护性。
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 若需支持浮点数输入,请改用 Double.parseDouble() 并调整正则(如 "-?\\d+(\\.\\d+)?"),但本例聚焦整数场景;
- 生产环境建议将校验逻辑封装为独立工具方法(如 isValidInteger(String)),便于复用与单元测试;
- Scanner 实例无需显式关闭(System.in 为系统流),但若用于文件等资源,务必使用 try-with-resources。
通过该方案,你彻底规避了 InputMismatchException,让 else 回归其本意——表达确定的业务逻辑分支,而非脆弱的异常兜底。










