如何确保Kotlin数据类中day非空时month也非空并定义指定构造器?
Kotlin数据类构造器约束实现方案
要实现你需要的这种带约束的Kotlin数据类,核心思路是把主构造器设为私有,只对外暴露符合要求的三个次构造器,这样就能完全避免出现day非空但month为空的非法实例。
直接上代码:
data class Date private constructor( val year: Int, val month: Int?, val day: Int? ) { // 仅传入年份的构造器 constructor(year: Int) : this(year, null, null) // 传入年份+月份的构造器 constructor(year: Int, month: Int) : this(year, month, null) // 传入年份+月份+日期的构造器 constructor(year: Int, month: Int, day: Int) : this(year, month, day) }
为什么这么做?
- 私有主构造器确保外部无法直接创建不符合约束的实例(比如
Date(2024, null, 15)这种非法情况根本写不出来) - 对外暴露的三个次构造器完全符合你的需求:都是不带默认可空字段的重载,分别对应仅年份、年份+月份、完整日期三种场景
- 数据类的所有特性(自动生成equals、hashCode、toString等)都不受影响
如果更倾向于用工厂方法的方式,也可以通过伴生对象实现,效果一致:
data class Date private constructor( val year: Int, val month: Int?, val day: Int? ) { companion object { fun of(year: Int) = Date(year, null, null) fun of(year: Int, month: Int) = Date(year, month, null) fun of(year: Int, month: Int, day: Int) = Date(year, month, day) } }
使用时调用Date.of(2024)、Date.of(2024, 10)或者Date.of(2024, 10, 20)即可,同样能保证约束生效。
内容的提问来源于stack exchange,提问作者Andrew Kolubov
相关产品推荐
相关产品推荐

