Java CalendarDate类实现:校验输入日期 无效则使用默认构造值
Java日历类实现优化方案
现有代码核心问题
- 内部使用String类型存储日期,每次调用getDate、getNextDate等方法都要重新解析,不仅性能低,还可能因为存储的字符串非法导致运行时异常
- 未对传入的日期做合法性校验,非法输入会直接导致后续方法抛出
DateTimeParseException - 默认
LocalDate.parse使用ISO_LOCAL_DATE格式(yyyy-MM-dd),和你输入的MM-dd-yyyy格式不匹配,运行直接报错 - 每个实例都创建独立的
DateTimeFormatter,该类是线程安全不可变类,完全可以设为全局常量复用,减少资源开销
优化后实现方案
你要求的带参构造函数、非法日期 fallback 逻辑可以通过封装校验方法复用实现,代码如下:
import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; public class CalendarDate { // 常量统一定义,全局复用 private static final DateTimeFormatter INPUT_DATE_FORMAT = DateTimeFormatter.ofPattern("MM-dd-yyyy"); private static final DateTimeFormatter OUTPUT_DATE_FORMAT = DateTimeFormatter.ofPattern("MMMM dd uuuu"); private static final LocalDate DEFAULT_DATE = LocalDate.of(2012, 1, 1); // 内部用LocalDate存储,避免重复解析和非法值问题 private LocalDate date; // 默认构造函数赋值默认日期 public CalendarDate(){ this.date = DEFAULT_DATE; } /** * 带日期参数的构造函数 * @param inputDate 输入的日期字符串,要求格式为MM-dd-yyyy */ public CalendarDate(String inputDate){ // 先调用无参构造初始化默认值 this(); // 调用setDate校验并赋值,非法则保留默认值 setDate(inputDate); } /** * 修改日期方法,合法则更新,非法保留原有值并给出提示 * @param inputDate 输入的新日期字符串 */ public void setDate(String inputDate){ try { // 按指定格式解析日期,合法则更新 this.date = LocalDate.parse(inputDate, INPUT_DATE_FORMAT); } catch (DateTimeParseException e) { // 解析失败给出友好提示,不修改原有日期 System.out.printf("警告:输入日期[%s]不合法,请使用MM-dd-yyyy格式的有效日期,将保留原有日期值%n", inputDate); } } public String getDate(){ return date.format(OUTPUT_DATE_FORMAT); } public String getNextDate(){ LocalDate nextDay = date.plusDays(1); return nextDay.format(OUTPUT_DATE_FORMAT); } public String getPriorDate(){ LocalDate priorDay = date.minusDays(1); return priorDay.format(OUTPUT_DATE_FORMAT); } public String getDayOfWeek(){ return date.getDayOfWeek().toString(); } } // 测试类 class CalendarTest { public static void main(String[] args){ // 测试合法输入 CalendarDate testDate1 = new CalendarDate("06-07-1992"); System.out.println(testDate1.getDate()); // 测试非法输入 CalendarDate testDate2 = new CalendarDate("02/31/2012"); System.out.println(testDate2.getDate()); // 测试setDate非法输入 testDate2.setDate("13-40-2023"); System.out.println(testDate2.getDate()); } }
方案优势
- 代码复用率高:校验逻辑统一封装在setDate中,构造函数直接调用,没有重复代码
- 性能更优:内部用LocalDate存储,避免每次读取都解析字符串,全局复用DateTimeFormatter减少对象创建开销
- 鲁棒性强:所有非法输入都会被捕获处理,不会出现运行时崩溃,符合你要求的非法输入保留默认值的需求
- 可维护性好:输入输出格式、默认值都统一定义为常量,修改时不需要改动业务逻辑
内容的提问来源于stack exchange,提问作者mattgcf
相关产品推荐
相关产品推荐

