Kotlin数据类 data class
- 使用关键字data class 创建一个只包含数据的类
data class DataClass(val userName: String, val pwd: String) {
}
- 1
- 2
反编译之后的java代码如下所示
public final class DataClass {
@NotNull
private final String userName;
@NotNull
private final String pwd;
@NotNull
public final String getUserName() {
return this.userName;
}
@NotNull
public final String getPwd() {
return this.pwd;
}
public DataClass(@NotNull String userName, @NotNull String pwd) {
Intrinsics.checkParameterIsNotNull(userName, "userName");
Intrinsics.checkParameterIsNotNull(pwd, "pwd");
super();
this.userName = userName;
this.pwd = pwd;
}
@NotNull
public final String component1() {
return this.userName;
}
@NotNull
public final String component2() {
return this.pwd;
}
@NotNull
public final DataClass copy(@NotNull String userName, @NotNull String pwd) {
Intrinsics.checkParameterIsNotNull(userName, "userName");
Intrinsics.checkParameterIsNotNull(pwd, "pwd");
return new DataClass(userName, pwd);
}
// $FF: synthetic method
// $FF: bridge method
@NotNull
public static DataClass copy$default(DataClass var0, String var1, String var2, int var3, Object var4) {
if ((var3 & 1) != 0) {
var1 = var0.userName;
}
if ((var3 & 2) != 0) {
var2 = var0.pwd;
}
return var0.copy(var1, var2);
}
public String toString() {
return "DataClass(userName=" + this.userName + ", pwd=" + this.pwd + ")";
}
public int hashCode() {
return (this.userName != null ? this.userName.hashCode() : 0) * 31 + (this.pwd != null ? this.pwd.hashCode() : 0);
}
public boolean equals(Object var1) {
if (this != var1) {
if (var1 instanceof DataClass) {
DataClass var2 = (DataClass)var1;
if (Intrinsics.areEqual(this.userName, var2.userName) && Intrinsics.areEqual(this.pwd, var2.pwd)) {
return true;
}
}
return false;
} else {
return true;
}
}
}
- 编译器会根据主构造函数生命的属性自动创建以下三个函数
- equals()、hashCode、toString()
- component1()、component2()返回对应下标位置的属性值,按照声明顺序排列
- copy()函数:根据旧对象重新new一个对象出来。
- 如果以上函数在类中已经被定义,或者其超类中继承,则编译器将不会生成
数据类语法限制
- 主构造函数至少含有一个参数
- 参数必须用val或者var标识
- 不能为abstract、open、sealed、inner
- 不能继承其他的类、但是可以实现接口
另外数据类可以在解构声明中使用
@JvmStatic
fun main(args: Array<String>) {
val dataClass = DataClass("LL", "123456")
val (username, pwd) = dataClass
println("${username} " + "---" + " ${pwd}")
}
- 1
- 2
- 3
- 4
- 5
- 6
Pair 和 Triple
Kotlin标准库提供了Pari和Triple数据类,分别表示二元组和三元组对象。
- Pari
// 泛型作为内部方法的返回,那么可以用 out
// 泛型对象作为函数的参数,那么可以用 in
data class DataClass<out A, out B>(private val userName: A, private val pwd: B) {
override fun toString(): String {
return "userName = " + userName + " userpwd = " + pwd
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
创建DataClass的时候,只能是二元组的参数
或者创建一个Pari 或者 Triple
val pair = Pair<Int, String>(12, "hello")
println(pair)
println(pair.first)
println(pair.second)
val triple = Triple<String, String, Int>("zhang", "男", 12)
println(triple.first)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
或者创建一个Map
var map = mapOf(1 to "A", 2 to "B", 3 to "C")
println(map)
- 1
- 2
输出结果
{1=A, 2=B, 3=C}
- 1
- Triple 使用也差不多
data class DataClass<out A, out B, out C>(private val userName: A, private val pwd: B, private val sex: C)
- 1
复制
复制使用 copy() 函数,我们可以使用该函数复制对象并修改部分属性, 对于上文的 User 类,其实现会类似下面这样:
fun copy(name: String = this.name, age: Int = this.age) = User(name, age)
实例
使用 copy 类复制 User 数据类,并修改 age 属性:
data class User(val name: String, val age: Int)
fun main(args: Array<String>) {
val jack = User(name = "Jack", age = 1)
val olderJack = jack.copy(age = 2)
println(jack)
println(olderJack)
}
输出结果为:
User(name=Jack, age=1)
User(name=Jack, age=2)
数据类以及解构声明
组件函数允许数据类在解构声明中使用:
val jane = User("Jane", 35)
val (name, age) = jane
println("$name, $age years of age") // prints "Jane, 35 years of age"
标准数据类
标准库提供了 Pair 和 Triple 。在大多数情形中,命名数据类是更好的设计选择,因为这样代码可读性更强而且提供了有意义的名字和属性。