
上QQ阅读APP看书,第一时间看更新
2.3.3 数据类
Kotlin的数据类使用data关键字来修饰类,例如:
data class User(var name:String,var password:String)
1.特性
编译器自动从主构造函数中声明的所有属性可以导出以下方法:
· equals()/hashCode()方法
· toString()方法
· componentN()方法
· copy()方法
我们通过反编译User.class来证实这些方法的存在,如图2-7所示。其中,componentN()方法对应主构造函数中的属性。有个多少属性,就会有多少个以component作为前缀的方法。

图2-7 data class User对象反编译后
copy()是复制函数,能够复制一个对象的全部属性,也能复制部分属性。例如下面的代码:

执行结果如下:
User(name=tony, password=123456, address=Address(street=renming)) true User(name=monica, password=123456, address=Address(street=renming)) User(name=tony, password=abcdef, address=Address(street=renming))
user1.address===user2.address打印的结果是true,表示二者内存地址相同。如果对象内部有引用类型的变量,通过拷贝后二者指向的是同一地址,表示为浅拷贝。所以data class的copy为浅拷贝。
另外,Kotlin中的“===”比较的是内存地址。
2.继承
数据类不能被继承。从刚才反编译的User.class可以看到,它是final类型的。那么如何在属于同一超类型的多个数据类之间共享属性、方法呢?可以考虑使用抽象类或者接口。
例如下面的代码,在父类Message中共享属性action使用abstract修饰,然后在其子类覆盖action。

执行结果如下:
{"action":"ping"} {"action":"ask","body":{"param1":"tt","param2":"qq"}}
在Kotlin 1.5之后,data class还支持Java 15的Records类,只要在data class上声明@JvmRecord即可。例如:
@JvmRecord data class User(var name:String,var password:String)