data class ModelA( val name: String = "", var age: Int = 10, var grade: Int = 6,)
· 主构造函数需要至少有一个参数;
· 主构造函数的所有参数需要标记为 val 或 var;
· 数据类不能被abstract、open、sealed或者internal修饰;
转换成Java类:
public final class ModelA { @NotNull private final String name; private int age; private int grade; @NotNull public final String getName() { return this.name; } public final int getAge() { return this.age; } public final void setAge(int var1) { this.age = var1; } public final int getGrade() { return this.grade; } public final void setGrade(int var1) { this.grade = var1; } public ModelA(@NotNull String name, int age, int grade) { Intrinsics.checkNotNullParameter(name, "name"); super(); this.name = name; this.age = age; this.grade = grade; } // $FF: synthetic method public ModelA(String var1, int var2, int var3, int var4, DefaultConstructorMarker var5) { if ((var4 & 1) != 0) { var1 = ""; } if ((var4 & 2) != 0) { var2 = 10; } if ((var4 & 4) != 0) { var3 = 6; } this(var1, var2, var3); } public ModelA() { this((String)null, 0, 0, 7, (DefaultConstructorMarker)null); } @NotNull public final String component1() { return this.name; } public final int component2() { return this.age; } public final int component3() { return this.grade; } @NotNull public final ModelA copy(@NotNull String name, int age, int grade) { Intrinsics.checkNotNullParameter(name, "name"); return new ModelA(name, age, grade); } // $FF: synthetic method public static ModelA copy$default(ModelA var0, String var1, int var2, int var3, int var4, Object var5) { if ((var4 & 1) != 0) { var1 = var0.name; } if ((var4 & 2) != 0) { var2 = var0.age; } if ((var4 & 4) != 0) { var3 = var0.grade; } return var0.copy(var1, var2, var3); } @NotNull public String toString() { return "ModelA(name=" + this.name + ", age=" + this.age + ", grade=" + this.grade + ")"; } public int hashCode() { String var10000 = this.name; return ((var10000 != null ? var10000.hashCode() : 0) * 31 + Integer.hashCode(this.age)) * 31 + Integer.hashCode(this.grade); } public boolean equals(@Nullable Object var1) { if (this != var1) { if (var1 instanceof ModelA) { ModelA var2 = (ModelA)var1; if (Intrinsics.areEqual(this.name, var2.name) && this.age == var2.age && this.grade == var2.grade) { return true; } } return false; } else { return true; } }}
可以看到data数据类帮我们生成了equals()、hashCode()、toString()、copy()函数。
当需要复制一个对象,并需要改变部分属性值时,copy()函数为此而生。
val modelA = ModelA(name = "A", age = 10, grade = 1)val modelB = modelA.copy(name = "B")log("modelA:$modelA,hashCode:${modelA.hashCode()}")log("modelB:$modelB,hashCode:${modelB.hashCode()}")//执行结果:modelA:ModelA(name=A, age=10, grade=1),hashCode:62776modelB:ModelA(name=B, age=10, grade=1),hashCode:63737
如果copy()函数中改变了对象中的属性,会通过new重新生成一个新对象,示例中通过结果中不同的hashCode值即可看到;而如果只是调用copy()函数,并未改变对象的属性值时,通过实验发现两者的hashCode值并未改变。
sealed密封类用来表示受限的类继承结构:当一个值为有限几种的类型、而不能有任何其他类型时。
可以将密封类对比枚举类:枚举常量只存在一个实例,而密封类的一个子类可以有可包含状态的多个实例。
sealed class Async<out T> { object Loading : Async<Nothing>() data class Success<out T>(val data: T) : Async<T>()}
转换成Java类:
//注意看,这里是abstract抽象类public abstract class Async { private Async() { } // $FF: synthetic method public Async(DefaultConstructorMarker $constructor_marker) { this(); } public static final class Loading extends Async { @NotNull public static final Async.Loading INSTANCE; private Loading() { super((DefaultConstructorMarker)null); } static { Async.Loading var0 = new Async.Loading(); INSTANCE = var0; } } public static final class Success extends Async { private final Object data; public final Object getData() { return this.data; } public Success(Object data) { super((DefaultConstructorMarker)null); this.data = data; } public final Object component1() { return this.data; } @NotNull public final Async.Success copy(Object data) { return new Async.Success(data); } // $FF: synthetic method public static Async.Success copy$default(Async.Success var0, Object var1, int var2, Object var3) { if ((var2 & 1) != 0) { var1 = var0.data; } return var0.copy(var1); } @NotNull public String toString() { return "Success(data=" + this.data + ")"; } public int hashCode() { Object var10000 = this.data; return var10000 != null ? var10000.hashCode() : 0; } public boolean equals(@Nullable Object var1) { if (this != var1) { if (var1 instanceof Async.Success) { Async.Success var2 = (Async.Success)var1; if (Intrinsics.areEqual(this.data, var2.data)) { return true; } } return false; } else { return true; } } }}
可以看到转换成Java类之后,sealed密封类自身是abstract抽象类,不能直接进行实例化。 sealed密封类的典型用法即是在when(){}中,当传入的是密封类时,不用再写else分支了,如:
fun processResult(result: Async<String>) { when (result) { is Async.Loading -> { // do something } is Async.Success -> { //do something } //这里不用再写else逻辑了 }}
阅读量:1443
点赞量:0
收藏量:0