为何ParseException未被捕获?Java日期校验异常排查
问题解答
1. 字母年份抛出异常却仍生成Worker的原因
你的isThisDateValid方法已经正确捕获了ParseException(控制台打印的异常栈就是证据),最终还是生成Worker对象的问题出在main方法的逻辑——你没有利用该方法的返回值做判断,不管验证是否通过,都直接用用户输入的年份字符串创建了Worker。
比如你的main方法大概率是类似这样的逻辑:
Scanner scanner = new Scanner(System.in); System.out.println("Enter name:"); String name = scanner.nextLine(); System.out.println("Enter position:"); String position = scanner.nextLine(); System.out.println("Enter year"); String year = scanner.nextLine(); // 调用了验证,但没用到返回值 isThisDateValid(year, "yyyy"); // 直接创建Worker,不管验证结果 Worker worker = new Worker(name, position, year); System.out.println(worker);
改成以下逻辑即可解决:
// 调用验证后根据结果处理 if (isThisDateValid(year, "yyyy")) { Worker worker = new Worker(name, position, year); System.out.println(worker); } else { System.out.println("年份格式错误,请重新输入"); }
2. 超长数字年份被接受的原因
SimpleDateFormat.setLenient(false)的作用是关闭宽松日期解析,比如拒绝2月30日、13月这种非法日期,但它不会限制年份的数字长度——yyyy格式本身就支持任意位数的数字年份,所以20023这种5位数字会被当成合法年份解析。
如果要限制年份必须是4位数字,需要额外添加正则校验:
// 在isThisDateValid方法开头增加校验 if (!dateToValidate.matches("\\d{4}")) { return false; }
修正后的完整验证方法
public class Main { public static boolean isThisDateValid(String dateToValidate, String dateFormat) { if (dateToValidate == null) { return false; } // 先校验年份为4位数字 if (!dateToValidate.matches("\\d{4}")) { return false; } SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); sdf.setLenient(false); try { Date date = sdf.parse(dateToValidate); } catch (ParseException exc) { exc.printStackTrace(); return false; } return true; } }
进阶建议:改用Java 8+的DateTimeFormatter
SimpleDateFormat是线程不安全的,推荐使用Java 8引入的DateTimeFormatter,它的校验更严谨,用法也更清晰:
public static boolean isThisDateValid(String dateToValidate) { if (dateToValidate == null || !dateToValidate.matches("\\d{4}")) { return false; } // 严格模式解析 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu") .withResolverStyle(ResolverStyle.STRICT); try { // 拼接月日确保完整日期解析 LocalDate.parse(dateToValidate + "-01-01", formatter); return true; } catch (DateTimeParseException e) { e.printStackTrace(); return false; } }
内容的提问来源于stack exchange,提问作者Ievgeniia Leleka
相关产品推荐
相关产品推荐

