kotlin語(yǔ)言學(xué)習(xí)11 ——kotlin的data class(數(shù)據(jù)類)

本節(jié)介紹kotlin的data class(數(shù)據(jù)類)

1赌渣、數(shù)據(jù)類的定義和反編譯分析

在Java中數(shù)據(jù)類中具有的 getter,setter方法韭山,可以通過(guò) IDEA或者eclipse來(lái)生成代碼障陶,但是有很多的冗余
當(dāng)然我們也可以使用Java的插件,lombok券勺,僅用幾個(gè)注釋就能解決蚕苇。

1.1、數(shù)據(jù)類的定義

但是在kotlin中检眯,我們可以直接使用 data 關(guān)鍵字來(lái)定義數(shù)據(jù)類

注意數(shù)據(jù)類的前提條件:

  • 1厘擂、主構(gòu)造方法至少要有一個(gè)參數(shù)
  • 2、所有的主構(gòu)造方法參數(shù)都需要被標(biāo)記為 var 或者 val
  • 3锰瘸、數(shù)據(jù)類不能是抽象刽严、open的、sealed(密封類)避凝、inner的類

數(shù)據(jù)類的定義示例:

data class Person(val name: String, var age: Int, var address: String)

數(shù)據(jù)類的使用:

fun main() {
    val person = Person("zhangsan", 20, "beijing")
    println(person)  
}

1.2舞萄、數(shù)據(jù)類的反編譯分析

接下來(lái)眨补,我們可以使用反編譯,對(duì)上面生成的數(shù)據(jù)類進(jìn)行深度的分析倒脓。(關(guān)于反編譯知識(shí)撑螺,看一看我之前的博客,點(diǎn)這里 ) 崎弃,以下是反編譯結(jié)果:

    Compiled from "DataClass.kt"
    public final class com.liang.kotlin.basic.data_class.Person {
      public final java.lang.String getName();
        Code:
           0: aload_0
           1: getfield      #11                 // Field name:Ljava/lang/String;
           4: areturn

      public final int getAge();
        Code:
           0: aload_0
           1: getfield      #19                 // Field age:I
           4: ireturn

      public final void setAge(int);
        Code:
           0: aload_0
           1: iload_1
           2: putfield      #19                 // Field age:I
           5: return

      public final java.lang.String getAddress();
        Code:
           0: aload_0
           1: getfield      #26                 // Field address:Ljava/lang/String;
           4: areturn

      public final void setAddress(java.lang.String);
        Code:
           0: aload_1
           1: ldc           #29                 // String <set-?>
           3: invokestatic  #35                 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
           6: aload_0
           7: aload_1
           8: putfield      #26                 // Field address:Ljava/lang/String;
          11: return

      public com.liang.kotlin.basic.data_class.Person(java.lang.String, int, java.lang.String);
        Code:
           0: aload_1
           1: ldc           #38                 // String name
           3: invokestatic  #35                 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
           6: aload_3
           7: ldc           #39                 // String address
           9: invokestatic  #35                 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
          12: aload_0
          13: invokespecial #42                 // Method java/lang/Object."<init>":()V
          16: aload_0
          17: aload_1
          18: putfield      #11                 // Field name:Ljava/lang/String;
          21: aload_0
          22: iload_2
          23: putfield      #19                 // Field age:I
          26: aload_0
          27: aload_3
          28: putfield      #26                 // Field address:Ljava/lang/String;
          31: return

      public final java.lang.String component1();
        Code:
           0: aload_0
           1: getfield      #11                 // Field name:Ljava/lang/String;
           4: areturn

      public final int component2();
        Code:
           0: aload_0
           1: getfield      #19                 // Field age:I
           4: ireturn

      public final java.lang.String component3();
        Code:
           0: aload_0
           1: getfield      #26                 // Field address:Ljava/lang/String;
           4: areturn

      public final com.liang.kotlin.basic.data_class.Person copy(java.lang.String, int, java.lang.String);
        Code:
           0: aload_1
           1: ldc           #38                 // String name
           3: invokestatic  #35                 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
           6: aload_3
           7: ldc           #39                 // String address
           9: invokestatic  #35                 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
          12: new           #2                  // class com/liang/kotlin/basic/data_class/Person
          15: dup
          16: aload_1
          17: iload_2
          18: aload_3
          19: invokespecial #49                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;)V
          22: areturn

      public static com.liang.kotlin.basic.data_class.Person copy$default(com.liang.kotlin.basic.data_class.Person, java.lang.String, int, java.lang.String, int, java.lang.Object);
        Code:
           0: iload         4
           2: iconst_1
           3: iand
           4: ifeq          12
           7: aload_0
           8: getfield      #11                 // Field name:Ljava/lang/String;
          11: astore_1
          12: iload         4
          14: iconst_2
          15: iand
          16: ifeq          24
          19: aload_0
          20: getfield      #19                 // Field age:I
          23: istore_2
          24: iload         4
          26: iconst_4
          27: iand
          28: ifeq          36
          31: aload_0
          32: getfield      #26                 // Field address:Ljava/lang/String;
          35: astore_3
          36: aload_0
          37: aload_1
          38: iload_2
          39: aload_3
          40: invokevirtual #53                 // Method copy:(Ljava/lang/String;ILjava/lang/String;)Lcom/liang/kotlin/basic/data_class/Person;
          43: areturn

      public java.lang.String toString();
        Code:
           0: new           #56                 // class java/lang/StringBuilder
           3: dup
           4: invokespecial #57                 // Method java/lang/StringBuilder."<init>":()V
           7: ldc           #59                 // String Person(name=
           9: invokevirtual #63                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          12: aload_0
          13: getfield      #11                 // Field name:Ljava/lang/String;
          16: invokevirtual #63                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          19: ldc           #65                 // String , age=
          21: invokevirtual #63                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          24: aload_0
          25: getfield      #19                 // Field age:I
          28: invokevirtual #68                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
          31: ldc           #70                 // String , address=
          33: invokevirtual #63                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          36: aload_0
          37: getfield      #26                 // Field address:Ljava/lang/String;
          40: invokevirtual #63                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          43: ldc           #72                 // String )
          45: invokevirtual #63                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          48: invokevirtual #74                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          51: areturn

      public int hashCode();
        Code:
           0: aload_0
           1: getfield      #11                 // Field name:Ljava/lang/String;
           4: dup
           5: ifnull        14
           8: invokevirtual #77                 // Method java/lang/Object.hashCode:()I
          11: goto          16
          14: pop
          15: iconst_0
          16: bipush        31
          18: imul
          19: aload_0
          20: getfield      #19                 // Field age:I
          23: invokestatic  #82                 // Method java/lang/Integer.hashCode:(I)I
          26: iadd
          27: bipush        31
          29: imul
          30: aload_0
          31: getfield      #26                 // Field address:Ljava/lang/String;
          34: dup
          35: ifnull        44
          38: invokevirtual #77                 // Method java/lang/Object.hashCode:()I
          41: goto          46
          44: pop
          45: iconst_0
          46: iadd
          47: ireturn

      public boolean equals(java.lang.Object);
        Code:
           0: aload_0
           1: aload_1
           2: if_acmpeq     56
           5: aload_1
           6: instanceof    #2                  // class com/liang/kotlin/basic/data_class/Person
           9: ifeq          58
          12: aload_1
          13: checkcast     #2                  // class com/liang/kotlin/basic/data_class/Person
          16: astore_2
          17: aload_0
          18: getfield      #11                 // Field name:Ljava/lang/String;
          21: aload_2
          22: getfield      #11                 // Field name:Ljava/lang/String;
          25: invokestatic  #91                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
          28: ifeq          58
          31: aload_0
          32: getfield      #19                 // Field age:I
          35: aload_2
          36: getfield      #19                 // Field age:I
          39: if_icmpne     58
          42: aload_0
          43: getfield      #26                 // Field address:Ljava/lang/String;
          46: aload_2
          47: getfield      #26                 // Field address:Ljava/lang/String;
          50: invokestatic  #91                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
          53: ifeq          58
          56: iconst_1
          57: ireturn
          58: iconst_0
          59: ireturn
    }

通過(guò)上面的反編譯甘晤,我們可以清楚的看到:
編譯器做增加了一下內(nèi)容:

1、equals/hasCode
2饲做、toString(),形式為:Person(name=..., age=..., address=...)
3安皱、針對(duì)屬性的componentN方法,并且是按照屬性的聲明順序來(lái)生成的
4艇炎、copy方法

2酌伊、數(shù)據(jù)類方法說(shuō)明

通過(guò)上面的反編譯class,接下來(lái)對(duì)編譯器生成出來(lái)的函數(shù)進(jìn)行探索缀踪。

2.1居砖、componentN()

componentN的方法主要在于,解構(gòu)聲明:

  • 解構(gòu):在主構(gòu)造方法中有多少個(gè)參數(shù)就會(huì)生成多少個(gè) component方法 (component1,component2... )
  • 這些方法返回對(duì)應(yīng)字段的值驴娃,component方法是用來(lái)實(shí)現(xiàn) 解構(gòu)聲明的

演示如圖所示:

componentN演示

2.2奏候、copy()

copy() : 作用在賦值的時(shí)候,很方便唇敞,
在Java中蔗草,一個(gè)對(duì)象的類成員如果如果被另一個(gè)對(duì)象復(fù)制,僅僅修改了一個(gè)參數(shù)疆柔,那么需要把這個(gè)對(duì)象的所有值都賦值給另一個(gè)對(duì)象咒精,這樣是非常麻煩的。
在kotlin中旷档,可以通過(guò)copy()方法執(zhí)行修改某一個(gè)參數(shù)
注意: 如果不加參數(shù)名字模叙,那么默認(rèn)是第一個(gè),必須明確參數(shù)名

compy演示

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鞋屈,一起剝皮案震驚了整個(gè)濱河市范咨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌厂庇,老刑警劉巖渠啊,帶你破解...
    沈念sama閱讀 221,888評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異权旷,居然都是意外死亡替蛉,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)灭返,“玉大人盗迟,你說(shuō)我怎么就攤上這事∥鹾” “怎么了罚缕?”我有些...
    開封第一講書人閱讀 168,386評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)怎静。 經(jīng)常有香客問(wèn)我邮弹,道長(zhǎng),這世上最難降的妖魔是什么蚓聘? 我笑而不...
    開封第一講書人閱讀 59,726評(píng)論 1 297
  • 正文 為了忘掉前任腌乡,我火速辦了婚禮,結(jié)果婚禮上夜牡,老公的妹妹穿的比我還像新娘与纽。我一直安慰自己,他們只是感情好塘装,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評(píng)論 6 397
  • 文/花漫 我一把揭開白布急迂。 她就那樣靜靜地躺著,像睡著了一般蹦肴。 火紅的嫁衣襯著肌膚如雪僚碎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,337評(píng)論 1 310
  • 那天阴幌,我揣著相機(jī)與錄音勺阐,去河邊找鬼。 笑死矛双,一個(gè)胖子當(dāng)著我的面吹牛渊抽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播背零,決...
    沈念sama閱讀 40,902評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼腰吟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼无埃!你這毒婦竟也來(lái)了徙瓶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,807評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤嫉称,失蹤者是張志新(化名)和其女友劉穎侦镇,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體织阅,經(jīng)...
    沈念sama閱讀 46,349評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡壳繁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闹炉。...
    茶點(diǎn)故事閱讀 40,567評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蒿赢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出渣触,到底是詐尸還是另有隱情羡棵,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評(píng)論 5 350
  • 正文 年R本政府宣布嗅钻,位于F島的核電站皂冰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏养篓。R本人自食惡果不足惜秃流,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望柳弄。 院中可真熱鬧舶胀,春花似錦、人聲如沸碧注。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)应闯。三九已至纤控,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間碉纺,已是汗流浹背船万。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留骨田,地道東北人耿导。 一個(gè)月前我還...
    沈念sama閱讀 48,995評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像态贤,于是被迫代替她去往敵國(guó)和親舱呻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評(píng)論 2 359