Java类中能否为Integer属性设置取值范围?禁止使用校验方法
在Java类中为数值属性设置取值范围(无需额外校验方法)
可以实现,核心思路是自定义受限的数值类型替代原生的int/Integer,让类型本身就只能生成合法范围内的值,从根源上避免非法取值,完全不需要编写单独的校验方法。
实现步骤
- 创建对应属性的受限类型,通过私有构造器限制实例化逻辑,仅允许合法值创建实例
- 在Date类中使用这些受限类型作为属性类型,而非原生int
示例代码
1. 自定义受限数值类型
// 受限年份类型:仅允许1900-2100的数值 public final class Year { public final int value; // 私有构造器,仅内部调用时做合法性校验 private Year(int value) { if (value < 1900 || value > 2100) { throw new IllegalArgumentException("年份必须在1900-2100之间"); } this.value = value; } // 静态工厂方法,对外提供唯一的实例创建入口 public static Year of(int value) { return new Year(value); } } // 受限月份类型:仅允许1-12的数值 public final class Month { public final int value; private Month(int value) { if (value < 1 || value > 12) { throw new IllegalArgumentException("月份必须在1-12之间"); } this.value = value; } public static Month of(int value) { return new Month(value); } } // 受限日期类型:仅允许1-31的数值 public final class Day { public final int value; private Day(int value) { if (value < 1 || value > 31) { throw new IllegalArgumentException("日期必须在1-31之间"); } this.value = value; } public static Day of(int value) { return new Day(value); } }
2. 修改后的Date类
public class Date { private Year year; private Month month; private Day day; // 构造器直接接收合法的受限类型实例,无需额外校验 public Date(Year year, Month month, Day day) { this.year = year; this.month = month; this.day = day; } // 修改属性时直接接收受限类型实例,天然保证合法性 public void setYear(Year year) { this.year = year; } public void setMonth(Month month) { this.month = month; } public void setDay(Day day) { this.day = day; } // 获取原生数值 public int getYear() { return year.value; } public int getMonth() { return month.value; } public int getDay() { return day.value; } }
使用方式
创建Date实例时,必须通过受限类型的of方法生成合法值:
// 合法示例 Date validDate = new Date(Year.of(2024), Month.of(10), Day.of(15)); // 非法示例:会直接抛出IllegalArgumentException Date invalidDate = new Date(Year.of(1899), Month.of(13), Day.of(32));
这种方式下,所有属性的取值范围由自定义类型本身保证,Date类中完全不需要编写任何校验逻辑,符合你“不允许使用任何方法进行有效性校验”的要求。
内容的提问来源于stack exchange,提问作者Dennis
相关产品推荐
相关产品推荐

