<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Kotlin 空類(lèi)型安全與智能類(lèi)型轉(zhuǎn)換

          共 3179字,需瀏覽 7分鐘

           ·

          2021-01-16 13:11

          作者:Maenj Ba lah
          來(lái)源:SegmentFault 思否社區(qū)



          一、前言


          在 Kotlin 中的類(lèi)與接口?中我們已經(jīng)講了 Kotlin 的?類(lèi)、接口?和?擴(kuò)展方法,今天我們來(lái)講 Kotlin 中的?空類(lèi)型安全?和?智能類(lèi)型轉(zhuǎn)換。




          二、Kotlin 空類(lèi)型安全


          2.1、空類(lèi)型安全概念


          Java 語(yǔ)言中是沒(méi)有空類(lèi)型安全這一概念的,所以寫(xiě) Java 代碼經(jīng)常會(huì)出現(xiàn)空指針異常,但是 Kotlin 致力于消除空引用所帶來(lái)的危險(xiǎn),所以就有了空類(lèi)型安全概念。


          下面這段代碼在 Kotlin 中是無(wú)法編譯通過(guò)的,因?yàn)?Kotlin 的 String 是不能接受空值的,所以這個(gè)賦值操作是不被允許的。


          var?nonNull:?String?=?"Hello"
          nonNull?=?null??//?不可空類(lèi)型,不能賦值為?null
          //?訪問(wèn)長(zhǎng)度的話,不需要空判斷
          val?length?=?nonNull.length


          IDE 報(bào)錯(cuò)如下所示:



          但是如果我們非得定義一個(gè)空值,也是有辦法的,Kotlin 為了 100% 兼容 Java,必須得實(shí)現(xiàn)接收空值,所以要接收空值可以在定義的時(shí)候加一個(gè) ?。


          但是這個(gè)時(shí)候這個(gè)變量就可能是空值,所以訪問(wèn)的時(shí)候就會(huì)比較嚴(yán)格,比如下面代碼中的 nullable.length 就會(huì)報(bào)錯(cuò),因?yàn)榭赡苡|發(fā)空指針異常。


          var?nullable:?String??=?"Hello"
          nullable?=?null??//?可空類(lèi)型,編譯通過(guò)
          val?length?=?nullable.length?//?可能觸發(fā)空指針,編譯保報(bào)錯(cuò)


          IDE 報(bào)錯(cuò)如下所示:




          這個(gè)時(shí)候我們想 nullable.length 不報(bào)錯(cuò)可以:


          1. 當(dāng)我們確定 nullable 不可能為空的時(shí)候,可以將 nullable 強(qiáng)轉(zhuǎn)為不可空類(lèi)型,如下所示:

            var?nullable:?String??=?"Hello"
            //?不會(huì)報(bào)錯(cuò)了(自己已經(jīng)知道了,這個(gè)?nullable?不可能為空)
            val?length?=?nullable!!.length


          2. 如果我們不確定 nullable 是否為空的時(shí)候,可以用 ?. 來(lái)實(shí)現(xiàn)安全訪問(wèn),如下所示:

            var?nullable:?String??=?"Hello"
            //?這種情況下如果?nullable?為空的話,那么返回的?length?也是空
            val?length?=?nullable?.length
            //?這時(shí)候?length?的類(lèi)型不是?Int,而是?Int?,所以可以寫(xiě)成下面這樣
            val?length:?Int??=?nullable?.length
            //?如果你想?length?的類(lèi)型是?Int?的話,可以加個(gè)默認(rèn)值,寫(xiě)成下面這樣
            val?length:?Int?=?nullable?.length??:?0??//?如果?nullable?.length?為空,?就返回0


          2.2、空類(lèi)型的繼承關(guān)系


          我們知道 Int 是 Number 的子類(lèi),所以通過(guò)下面的代碼我們就可以知道 String 應(yīng)該是 String? 的子類(lèi)。

          var?a:?Int?=?2
          var?b:?Number?=?10.0

          a?=?b?//?Type?mismatch,報(bào)錯(cuò)
          b?=?a?//?OK

          var?x:?String?=?"Hello"
          var?y:?String??=?"World"

          x?=?y?//?Type?mismatch,報(bào)錯(cuò)
          y?=?x?//?OK

          2.3、Kotlin 空類(lèi)型安全回顧





          三、Kotlin 智能類(lèi)型轉(zhuǎn)換


          3.1、智能類(lèi)型轉(zhuǎn)換例子


          例子1:

          我們先來(lái)寫(xiě)一個(gè) Java 的類(lèi)型轉(zhuǎn)換:

          //?定義一個(gè)接口
          public?interface?Kotliner?{
          }

          //?定義一個(gè)類(lèi)?Person?實(shí)現(xiàn)?Kotliner?接口
          public?class?Person?implements?Kotliner?{
          ????public?final?String?name;
          ????public?final?int?age;

          ????public?Person(String?name,?int?age)?{
          ????????this.name?=?name;
          ????????this.age?=?age;
          ????}

          ????public?static?void?main(String[]?args)?{
          ????????//?用子類(lèi)的實(shí)例賦值給接口的引用
          ????????Kotliner?kotliner?=?new?Person("Test",?20);
          ????????//?這里已經(jīng)判斷了是不是?Person,但是下面還是要強(qiáng)制類(lèi)型轉(zhuǎn)換
          ????????if?(kotliner?instanceof?Person)?{
          ????????????System.out.println(kotliner.name);??//?這樣寫(xiě)報(bào)錯(cuò)
          ????????????System.out.println(((Person)?kotliner).name);??//?正確寫(xiě)法
          ????????}
          ????}
          }

          同樣的代碼在 Kotlin 中就可以實(shí)現(xiàn)智能類(lèi)型轉(zhuǎn)換,不需要強(qiáng)制類(lèi)型轉(zhuǎn)換:

          val?kotliner:?Kotliner?=?Person("Test",?20)
          if?(kotliner?is?Person)?{
          ????println((kotliner?as?Person).name)??//?不需要強(qiáng)轉(zhuǎn),可以智能轉(zhuǎn)換,所以下面的寫(xiě)法就可以了
          ????println(kotliner.name)
          }

          例子2:

          下面這段代碼定義了一個(gè) value, 類(lèi)型是 String?,if 判斷其不為空,所以在 if 判斷這個(gè)括號(hào)里面,value 的類(lèi)型會(huì)被智能轉(zhuǎn)換成 String,當(dāng)然出了括號(hào),value 的類(lèi)型就又是 String? 了。


          var?value:?String??=?null
          value?=?"Test"
          if?(value?!=?null)?{
          ????//?value:?String???==>??String
          ????println(value.length)
          }
          //?value:?String?
          ...

          3.2、不支持智能類(lèi)型轉(zhuǎn)換的情況


          下面這種情況就不支持智能類(lèi)型轉(zhuǎn)換,因?yàn)檫@個(gè)公共變量很多地方都可以訪問(wèn),所以我們?cè)谂袛嗖粸榭罩螅锌赡軇e的線程又把 tag 改成了空,所以這種情況智能類(lèi)型轉(zhuǎn)換就失效了。


          //?在?main?函數(shù)之外定義一個(gè)公共變量
          var?tag:?String??=?null

          fun?main()?{
          ????if(tag?!=?null)?{
          ????????//?有可能被改成空
          ????????println(tag.length)??//?報(bào)錯(cuò),不支持智能類(lèi)型轉(zhuǎn)換
          ????}
          }

          3.3、幾個(gè)建議


          • 盡可能使用 val 來(lái)聲明不可變引用,讓程序的含義更加清晰確定;
          • 盡可能減少函數(shù)對(duì)外部變量的訪問(wèn);
          • 必要的時(shí)候曾創(chuàng)建局部變量指向外部變量,避免因它變化引起程序錯(cuò)誤。


          3.4、Kotlin 智能類(lèi)型轉(zhuǎn)換





          四、小結(jié)


          本篇博客主要講了 Kotlin 中的空類(lèi)型安全和智能類(lèi)型轉(zhuǎn)換,下一節(jié)我們講 Kotin 中的表達(dá)式。



          五、源碼


          源碼?已上傳至 github,有需要可以直接下載。
          https://github.com/kdwu/KotlinLearning



          點(diǎn)擊左下角閱讀原文,到?SegmentFault 思否社區(qū)?和文章作者展開(kāi)更多互動(dòng)和交流。

          -?END -

          瀏覽 36
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                    <th id="afajh"><progress id="afajh"></progress></th>
                    久久国产劲暴∨内射新川 | AV性淫 | 日韩性爱无码视频 | 国产精品又黄又爽又色无遮挡 | 豆花一区在线观看 |