I have these fields in my data class:
val year: Int,
val month: Int? = null,
val day: Int? = null,
How can I insure via constructor that If day
in not-null, month
is not null as well?
Ideally, I wanna have only 3 constructors without default nullable fields at all.
(year: Int) (year: Int, month: Int) and (year: Int, month: Int, day: Int)
You can create a normal class, with a private constructor, and add your overloaded constructors:
class X 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 as Int?)
// Optionally create equals, hashCode, toString and componentN methods...
}
If you need any of the extra methods that a data class
would have auto-generated, just add them manually, or let your IDE generate them for you.
Rationale
Why did we create a normal class? Well, you could create a data class with a private constructor, but that wouldn't prevent the user of your class from calling the copy
function and passing invalid parameters to it, such as a day with a null month.
Unlike toString
, hashCode
and equals
, you cannot override the copy
function or disable it in any way. If you declare your class as a data class, you'll get an unwanted copy
function that you can't get rid of. With a normal class, you can define your own logic in the copy
function, though you probably wouldn't want to define it at all as it's problematic.