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)