1、语法
data 修饰的类
Kotlin
data class User(val name: String, val age: Int)
编译器自动从主构造函数中声明的所有属性导出以下成员:
- .equals()/.hashCode() 对
- .toString() 格式是 "User(name=John, age=42)"
- .componentN() 按声明顺序对应于所有属性
- .copy() 函数
2、规则
数据类必须满足以下要求:
- 主构造函数需要至少有一个参数
- 主构造函数的所有参数需要标记为
val
或var
- 数据类不能是抽象、开放、密封或者内部的
数据类成员的生成遵循关于成员继承的这些规则:
- 如果在数据类体中有显式实现
.equals()
、.hashCode()
或者.toString()
,或者这些函数在父类中有final
实现,那么不会生成这些函数,而会使用现有函数 - 如果超类型具有
open
的.componentN()
函数并且返回兼容的类型, 那么会为数据类生成相应的函数,并覆盖超类的实现;如果超类型的这些函数由于签名不兼容或者是 final 而导致无法覆盖,那么会报错 - 不允许为
.componentN()
以及.copy()
函数提供显式实现
3、类体中属性
声明在类体中的属性,将在生成的实现中被排除
Kotlin
data class Person(val name: String) { // 编译器只使用主构造函数内部定义的属性
var age: Int = 0 // 被编译器排除
}
fun main() {
val person1 = Person("John")
val person2 = Person("John")
person1.age = 10
person2.age = 20
println("person1 == person2: ${person1 == person2}")
// person1 == person2: true // age被排除,只检查name属性的相等性
println("person1 with age ${person1.age}: ${person1}")
// person1 with age 10: Person(name=John)
println("person2 with age ${person2.age}: ${person2}")
// person2 with age 20: Person(name=John)
}
4、复制
使用.copy()函数复制对象,允许保持某些属性不变的同时修改一些属性
Kotlin
fun copy(name: String = this.name, age: Int = this.age) = User(name, age)
val jack = User(name = "Jack", age = 1)
val olderJack = jack.copy(age = 2)
5、解构
component 函数 可在解构中使用
Kotlin
val jane = User("Jane", 35) // 数据类对象
val (name, age) = jane // 解构对象
println("$name, $age years of age")
// Jane, 35 years of age