示例:
data class Car (
val type: TypeEnum,
val brand: BrandEnum,
val modelNumber: Int)
{
constructor(val type: TypeEnum,
val brand: BrandEnum,
val input: String) : this (
type,
brand,
Valdidator.validateModelNumber(input)
)
}
在上面的代码中,方法validateModelNumber()验证原始输入,如果型号具有无效格式,则引发异常。我想强迫用户每次要创建Car对象时都要使用此构造函数。
本质上:我想确保没有无效的Car对象存在,同时仍使代码尽可能不变。
答案 0 :(得分:1)
您可以改用init
块。像这样
data class Car (
val type: TypeEnum,
val brand: BrandEnum,
val modelNumber: Int)
{
init {
Valdidator.validateModelNumber(input)
}
}
答案 1 :(得分:0)
如果只需要在主构造函数中指定的参数/属性,则使用init
块进行验证(根据另一个答案)可以很好地工作。但是,还有其他方法。
如果您不希望其他代码使用主构造函数,则可以通过更改以下内容使其成为private
:
data class Car(
收件人:
data class Car private constructor(
然后,您可以将公共二级构造器留给其他类使用,如问题所示。但是,这仍然有些限制,因为在调用主构造函数之前您无法进行任何认真的处理。
因此通常的模式是在随播对象中具有私有构造函数和工厂方法。这更加灵活:您可以在调用实际的构造函数之前和之后进行任何数量的处理;您甚至可以返回缓存的实例,子类实例等。
通过使用适当的参数将其实现为operator fun invoke()
,可以使这些外观像构造函数一样。在这种情况下,可能看起来像这样:
data class Car private constructor(
val type: TypeEnum,
val brand: BrandEnum,
val modelNumber: Int)
{
companion object {
operator fun invoke(type: TypeEnum, brand: BrandEnum, input: String)
= Car(type, brand, Validator.validateModelNumber(input))
}
}
然后您可以使用以下示例创建实例:
Car(TypeEnum.SPORTS, BrandEnum.ASTON_MARTIN, "DB5")
看起来像普通的构造函数。