侧边栏壁纸
博主头像
爱探索

行动起来,活在当下

  • 累计撰写 42 篇文章
  • 累计创建 11 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

kotlin-DataClass详解

jelly
2024-07-30 / 0 评论 / 0 点赞 / 31 阅读 / 0 字

DataClass详解

  1. 基本使用
  2. data class与普通类对比
  3. 使用注意事项

1. 基本使用


data class 类名(成员变量){
    类体
}

//1. data class 不能继承,也不能增加 open 关键字
//2. ()中成员变量即时成员变量还是构造函数参数(也就是必须有val或var)
//3. 不能有其他构造函数
//4. 类体可以省略

//示例:

data class Student (val name:String,var age:String)

2. data class与普通类对比


//data class 


@Metadata(
   mv = {1, 9, 0},
   k = 1,
   d1 = {"\u0000&\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0010\u000e\n\u0000\n\u0002\u0010\b\n\u0000\n\u0002\u0010\f\n\u0002\b\u000e\n\u0002\u0010\u000b\n\u0002\b\u0004\b\u0086\b\u0018\u00002\u00020\u0001B\u001d\u0012\u0006\u0010\u0002\u001a\u00020\u0003\u0012\u0006\u0010\u0004\u001a\u00020\u0005\u0012\u0006\u0010\u0006\u001a\u00020\u0007¢\u0006\u0002\u0010\bJ\t\u0010\u0011\u001a\u00020\u0003HÆ\u0003J\t\u0010\u0012\u001a\u00020\u0005HÆ\u0003J\t\u0010\u0013\u001a\u00020\u0007HÆ\u0003J'\u0010\u0014\u001a\u00020\u00002\b\b\u0002\u0010\u0002\u001a\u00020\u00032\b\b\u0002\u0010\u0004\u001a\u00020\u00052\b\b\u0002\u0010\u0006\u001a\u00020\u0007HÆ\u0001J\u0013\u0010\u0015\u001a\u00020\u00162\b\u0010\u0017\u001a\u0004\u0018\u00010\u0001HÖ\u0003J\t\u0010\u0018\u001a\u00020\u0005HÖ\u0001J\t\u0010\u0019\u001a\u00020\u0003HÖ\u0001R\u001a\u0010\u0004\u001a\u00020\u0005X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\t\u0010\n\"\u0004\b\u000b\u0010\fR\u0011\u0010\u0002\u001a\u00020\u0003¢\u0006\b\n\u0000\u001a\u0004\b\r\u0010\u000eR\u0011\u0010\u0006\u001a\u00020\u0007¢\u0006\b\n\u0000\u001a\u0004\b\u000f\u0010\u0010¨\u0006\u001a"},
   d2 = {"LStudent;", "", "name", "", "age", "", "sex", "", "(Ljava/lang/String;IC)V", "getAge", "()I", "setAge", "(I)V", "getName", "()Ljava/lang/String;", "getSex", "()C", "component1", "component2", "component3", "copy", "equals", "", "other", "hashCode", "toString", "KoltinDemo"}
)
public final class Student {
   @NotNull
   private final String name;
   private int age;
   private final char sex;

   @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 char getSex() {
      return this.sex;
   }

   public Student(@NotNull String name, int age, char sex) {
      Intrinsics.checkNotNullParameter(name, "name");
      super();
      this.name = name;
      this.age = age;
      this.sex = sex;
   }

   @NotNull
   public final String component1() {
      return this.name;
   }

   public final int component2() {
      return this.age;
   }

   public final char component3() {
      return this.sex;
   }

   @NotNull
   public final Student copy(@NotNull String name, int age, char sex) {
      Intrinsics.checkNotNullParameter(name, "name");
      return new Student(name, age, sex);
   }

   // $FF: synthetic method
   public static Student copy$default(Student var0, String var1, int var2, char 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.sex;
      }

      return var0.copy(var1, var2, var3);
   }

   @NotNull
   public String toString() {
      return "Student(name=" + this.name + ", age=" + this.age + ", sex=" + this.sex + ")";
   }

   public int hashCode() {
      String var10000 = this.name;
      return ((var10000 != null ? var10000.hashCode() : 0) * 31 + Integer.hashCode(this.age)) * 31 + Character.hashCode(this.sex);
   }

   public boolean equals(@Nullable Object var1) {
      if (this != var1) {
         if (var1 instanceof Student) {
            Student var2 = (Student)var1;
            if (Intrinsics.areEqual(this.name, var2.name) && this.age == var2.age && this.sex == var2.sex) {
               return true;
            }
         }

         return false;
      } else {
         return true;
      }
   }
}

//普通类

@Metadata(

@Metadata(
   mv = {1, 9, 0},
   k = 1,
   d1 = {"\u0000\u001e\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0010\u000e\n\u0000\n\u0002\u0010\b\n\u0000\n\u0002\u0010\f\n\u0002\b\n\u0018\u00002\u00020\u0001B\u001d\u0012\u0006\u0010\u0002\u001a\u00020\u0003\u0012\u0006\u0010\u0004\u001a\u00020\u0005\u0012\u0006\u0010\u0006\u001a\u00020\u0007¢\u0006\u0002\u0010\bR\u001a\u0010\u0004\u001a\u00020\u0005X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\t\u0010\n\"\u0004\b\u000b\u0010\fR\u0011\u0010\u0002\u001a\u00020\u0003¢\u0006\b\n\u0000\u001a\u0004\b\r\u0010\u000eR\u0011\u0010\u0006\u001a\u00020\u0007¢\u0006\b\n\u0000\u001a\u0004\b\u000f\u0010\u0010¨\u0006\u0011"},
   d2 = {"LStudent;", "", "name", "", "age", "", "sex", "", "(Ljava/lang/String;IC)V", "getAge", "()I", "setAge", "(I)V", "getName", "()Ljava/lang/String;", "getSex", "()C", "KoltinDemo"}
)
public final class Student {
   @NotNull
   private final String name;
   private int age;
   private final char sex;

   @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 char getSex() {
      return this.sex;
   }

   public Student(@NotNull String name, int age, char sex) {
      Intrinsics.checkNotNullParameter(name, "name");
      super();
      this.name = name;
      this.age = age;
      this.sex = sex;
   }
}


将两种不同类转成java我们看到data class 构造函数 成员变量基本与普通class一样,但是多了几个函数,具体函如下:

  • public String toString()
  • public int hashCode()
  • public boolean equals(@Nullable Object var1)
  • public final Student copy(@NotNull String name, @NotNull String age)
  • public static Student copy$default(Student var0, String var1, String var2, int var3, Object var4)
  • public final String component1()
  • public final String component2()

2.1. toString函数




    public String toString() {
      return "Student(name=" + this.name + ", age=" + this.age + ", sex=" + this.sex + ")";
   }


转成java 我们看到toString实际上就是调用各个成员变量的toString函数并组成新的字符串

2.2. hashCode


   public int hashCode() {
      String var10000 = this.name;
      return ((var10000 != null ? var10000.hashCode() : 0) * 31 + Integer.hashCode(this.age)) * 31 + Character.hashCode(this.sex);
   }

    

转成java 我们看到hashCode实际上就是调用各个成员变量的hashCode函数并组成新hashCode

因为java常量池原因,以及kotlin一些类自身hashcode的实现,两个成员变量值一样的对象他们Hash一致。

2.3. equals


   public boolean equals(@Nullable Object var1) {
      if (this != var1) {//对比引用,如果是同一个直接返回true
         if (var1 instanceof Student) { //对比类型
            Student var2 = (Student)var1;
            //引用类型调用equals对比,基础类型使用==对比值
            if (Intrinsics.areEqual(this.name, var2.name) && this.age == var2.age && this.sex == var2.sex) {
               return true;
            }
         }

         return false;
      } else {
         return true;
      }
   }


    // 示例

    data class Student(val name: String, var age: Int, val sex: Char) 

    val studentA = Student(String("张三".toCharArray()), 15, '男')
    val studentB = Student(String("张三".toCharArray()), 15, '男')
    println(studentB===studentA) //返回false
    println(studentB == studentA)//返回true


copy


   public final Student copy(@NotNull String name, int age, char sex) {
      Intrinsics.checkNotNullParameter(name, "name");
      return new Student(name, age, sex);
   }
   //实际就是创建一个新对象

3. 使用注意事项

  1. 重写了hashcode,两个对象的hashcode对比可能一样。导致有的android库在创建型对象后也不会触发更新,如liveData
  2. 构造函数必须有一个参数
0

评论区