# Kotlin data数据类、copy()函数、sealed密封类 站点:答源(https://www.dandroid.cn/) 原文:https://www.dandroid.cn/archives/19810 Canonical:https://www.dandroid.cn/archives/19810 作者:admin 发布日期:2023-09-10 最后更新:2023-09-10 06:41 分类:Kotlin 内容类型:post 说明:本页是原文的纯文本镜像,供大模型与检索器完整读取;不含导航、广告、付费框。引用请以上方「原文」链接为准。 ## 正文 data数据类 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()函数 当需要复制一个对象,并需要改变部分属性值时,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:62776 modelB:ModelA(name=B, age=10, grade=1),hashCode:63737 如果copy()函数中改变了对象中的属性,会通过new重新生成一个新对象,示例中通过结果中不同的hashCode值即可看到;而如果只是调用copy()函数,并未改变对象的属性值时,通过实验发现两者的hashCode值并未改变。 sealed密封类 sealed密封类用来表示受限的类继承结构:当一个值为有限几种的类型、而不能有任何其他类型时。 可以将密封类对比枚举类:枚举常量只存在一个实例,而密封类的一个子类可以有可包含状态的多个实例。 sealed class Async { object Loading : Async() data class Success(val data: T) : Async() } 转换成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) { when (result) { is Async.Loading -> { // do something } is Async.Success -> { //do something } //这里不用再写else逻辑了 } } 文章来源于互联网:Kotlin data数据类、copy()函数、sealed密封类 --- 由 答源 DAN 底座 1.4.1 生成 · 2026-11-09T20:34:26+00:00