- 数据类用关键字
data
标识
data class User(var name: String, var age: Int)
- 编译器自动从数据类的主构造函数中声明的所有属性导出以下成员
equals()/hashCode()
对;toString()
,格式为User(name=Marry, age=18)
;componentN()
函数 按声明顺序对应于所有属性;copy()
函数。
- 为了确保生成的代码的一致性以及有意义的行为,数据类必须满足以下要求:
- 必须要有主构造函数;
- 主构造函数需要至少有一个参数;
- 主构造函数的所有参数需要标记为 val 或 var;
- 数据类不能是抽象、开放、密封或者内部的;
- (在1.1之前)数据类只能实现接口。
- 数据类的成员生成遵循成员继承的这些规则:
- 如果在数据类体中有显式实现
equals()
、hashCode()
或者toString()
,或者这些函数在父类中有 final 实现,那么不会生成这些函数,而会使用现有函数; - 如果超类型具有
open
的componentN()
函数,并且返回兼容的类型, 那么会为数据类生成相应的函数,并覆盖超类的实现。如果超类型的这些函数由于签名不兼容或者是 final 而导致无法覆盖,那么会报错; - 从一个已具
copy(……)
函数且签名匹配的类型派生一个数据类在 Kotlin 1.2 中已弃用,并且在 Kotlin 1.3 中已禁用。 - 不允许为
componentN()
以及copy()
函数提供显式实现。
- 在 JVM 中,如果生成的类需要含有一个无参的构造函数,只要在主构造函数中为所有的属性指定默认值即可。
data class User(var name: String = "", var age: Int = 0)
fun main(args: Array<String>) {
val u = User() // 数据类定义时,主构造函数所有属性都制定了默认值,那么声明对象时,可以不带参数
println(u)
}
- 在数据类体中可定义属性,不会在自动生成的函数(如:
toString()
、equals()
、hashCode()
以及copy()
)中使用(只有在主构造函数定义的属性才会使用)
data class User(var name: String = "", var age: Int = 0) {
var addr: String = ""
}
fun main(args: Array<String>) {
val u = User()
println(u)
}
以上示例中,自动生成的
toString()
输出时不带内部声明的addr
属性。