<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] ## Kotlin相比于Java | 相比于java | 描述????????????????????????| | ------- | ------------------------- | | 方式更多????| 類型檢查,除了提供了**is運算符**還提供了**!is運算符** | | 更智能?????| 類型檢查,會進行變量類型的智能轉換?????????| | 方式更多????| 類型轉換,提供了**as運算符**和**as?運算符**??????| | 更安全?????| 類型轉換,使用as?運算符可以避免轉換異常?????| ## **類型檢查(is和!is運算符)** ### 回顧Java中instanceof 在**Java 中,instanceof 運算符用來在運行時檢測對象是否是特定類的一個實例**。基本格式如下: ``` boolean result = someObj instanceof Classs ``` * result,返回結果,true表示是Class的實例,false表示不是Class的實例; * someObj,必選項,任意對象; * Class,必選項,任意對象類; 我們編寫一個簡單案例,回顧下instanceof運算符的使用,參考代碼: ~~~ class InstanceOfDemo { public static void main(String[] args) { String str = "hello Kotlin"; getStringLength(str); } public static void getStringLength(Object obj) { if (obj instanceof String) { System.out.println("參數是字符串,長度是:" + ((String) obj).length()); } else { System.out.println("參數不是字符串類型"); } } } ~~~ 運行結果 ``` 參數是字符串,長度是:12 Process finished with exit code 0 ``` 針對以上代碼,我們注意第18行,我們把object當做字符串使用,這個地方進行了類型的強制轉換。 ### **is運算符和!is運算符** 在Kotlin中,可以使用is運算符用來在運行時檢測對象是否是特定類的一個實例。基本格式如下: ~~~ boolean result =someObj is Class ~~~ * result,返回結果,true表示是Class的實例,false表示不是Class的實例; * someObj,必選項,任意對象; * Class,必選項,任意對象類; 我們編寫一個簡單案例,看看`is`運算符的使用,參考代碼: ~~~ fun main(args: Array<String>) { val str = "hello kotlin" getStringLength(str) getStringLength2(str) } fun getStringLength(obj: Any) { if (obj is String) { //直接調用String方法,無需轉換 println("字符串的長度是:" + obj.length)//不用強轉換,kotlin已完成智能轉換 } else { println("參數不是字符串類型") } } fun getStringLength2(obj: Any) { if (obj !is String) { println("參數不是字符串類型") } else { //直接調用String方法,無需轉換 println("字符串的長度是:" + obj.length)//不用強轉換,kotlin已完成智能轉換 } } ~~~ 運行結果 ``` 字符串的長度是:12 字符串的長度是:12 Process finished with exit code 0 ``` 針對以上代碼第4行代碼,直接使用了String類的length方法。`!is`是一個與is操作符相對應的操作符,也就是類型不匹配的意思。我們直接參考代碼,如上面代碼所示。 針對以上代碼第2行使用了`!is`運算符。第6行代碼,直接使用了String類的length方法。 * **PS**:如果一個不可變的局部變量或屬性已經判斷出為某類型,那么檢測后的分支中可以直接當作該類型使用,無需顯式轉換: ``` fun getLength(obj: Any): Int? { var result = 0 if (obj is String) { // `obj` 在該條件分支內自動轉換成 `String` println(obj::class) //class java.lang.String result = obj.length println(result) } // 在離開類型檢測分支后,`obj` 仍然是 `Any` 類型 println(obj::class) // class java.lang.Object return result } ``` ### **智能轉換** **如果使用了`is`或者`!is`運算符,Kotlin就會對類型進行智能轉換,不用像Java還需要進行強轉類型轉換**,我們看到之前的代碼,obj沒有轉換為String類型,直接調用了String類的length方法。 總結起來,在if語句、else語句、邏輯或、邏輯與、when表達式都能感受到is和!is運算符帶來的智能轉換,參考代碼: ~~~ fun testFun(obj: Any) { //if條件中,智能轉換 if (obj is String) { obj.length } //else條件中,智能轉換 if (obj !is String) { } else { obj.length } //邏輯或運算符右側,智能轉換 if (obj !is String || obj.length == 0) { } //邏輯與運算符右側,智能轉換 if (obj is String && obj.length > 0) { } //when表達式,智能轉換 when (obj) { is Int -> print(obj + 1) is String -> print(obj.length + 1) is IntArray -> print(obj.sum()) } } ~~~ ## **強制轉換:`as`和`as?`運算符** 我們看到,智能轉換后,就可以調用某一個類的特定方法。我們**還可以通過`as`和`as?`運算符強制類型轉換**,然后調用對應類的對應方法。 **as運算符(“不安全的”轉換操作符)** 通常,如果轉換是不可能的,轉換操作符會拋出一個異常。因此,我們稱之為*不安全的*。 Kotlin 中的不安全轉換由中綴操作符*as*(參見[operator precedence](http://www.kotlincn.net/docs/reference/grammar.html#precedence))完成 ``` val x: String = y as String ``` >[info]注意: 一、*null*不能轉換為`String`因該類型不是[可空的](http://www.kotlincn.net/docs/reference/null-safety.html), 即如果`y`為空,上面的代碼會拋出一個異常。 為了匹配 Java 轉換語義,我們必須在轉換右邊有可空類型,就像`val x: String? = y as String?` 二、as運算符用于執行引用類型的顯式類型轉換。如果要轉換的類型與指定的類型兼容,轉換就會成功進行;如果類型不兼容,使用 as? 運算符就會返回值null。 三、在Kotlin中,子類是禁止轉換為父類型的。 按照Liskov替換原則,父類轉換為子類是對OOP的嚴重違反,不提倡、也不建議。嚴格來說,父類是不能轉換為子類的,子類包含了父類所有的方法和屬性,而父類則未必具有和子類同樣成員范圍,所以這種轉換是不被允許的,即便是兩個具有父子關系的空類型,也是如此。 我們參考如下案例: ~~~ fun main(args: Array<String>) { val a = "5" val b = a as String println(b.length) } ~~~ 結果如下 ``` 1 Process finished with exit code 0 ``` 針對以上代碼第3行完成了類型的轉換,第4行我們在使用String類的length方法的時候IDE沒有提示錯誤。代碼也成功的輸出了結果。 我們對變量a的值稍作改變轉換,再看如下結果: ~~~ fun main(args: Array<String>) { val a = 5 val b = a as String println(b.length) } ~~~ 報錯如下 ``` Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at day02.AsDemoKt.main(AsDemo.kt:12) Process finished with exit code 1 ``` 針對以上代碼第3行完成了類型的轉換,第4行我們在使用String類的length方法的時候IDE同樣沒有提示錯誤。但是,代碼在運行的時候就提示了類型轉換異常。甚至,IDE在as關鍵字的地方,也有相應的提示,參考截圖: ![](https://i.loli.net/2019/04/19/5cb9a53451b96.png) 到這里,我們得到兩個結論。 第一,Kotlin里面,Int類型不能使用as轉換為String類型。 第二,使用as運算符進行類型轉換,如果轉換錯誤,會拋出異常。 **安全轉換操作符as?** 至此,我們知道使用as運算符進行類型轉換,和常規的Java 類型轉換一樣,如果被轉換的值不是你試圖轉換的類型,就會拋出ClassCastException 異常,當然可以結合is 檢查來確保這個值擁有合適的類型。但是作為一種安全簡潔的語言, Kotlin 沒有更優雅的解決方案嗎?當然有。使用as?,`as?`運算符嘗試把值轉換成指定的類型, 如果值不是合適的類型就返回null ![](https://box.kancloud.cn/0199aac75ac7467ff784be69544d7150_488x147.png) “as?”運算符,是kotlin提供的安全的類型運算符,使用“as?”進行類型轉換的時候,如果轉換失敗,則會返回null,而不會拋出異常,參考代碼: ~~~ fun main(args: Array<String>) { val a = 5 val b = a as? String println(b?.length) } ~~~ 運行結果 ``` null Process finished with exit code 0 ``` 針對以上代碼第3行進行類型轉換的時候使用了安全轉換符“?.”。通過運行結果,我們得到結論,Int類型變量不能通過安全轉換符“as?”轉換為String類。但是Int確實無法轉String,所以返回了null。 **使用安全轉換實現equals** ~~~ package A基礎 /** *使用安全轉換實現equals * 安全轉換as?和Elvis運算符結合使用 */ class Student(val firstName:String,val lastName:String){ override fun equals(other: Any?): Boolean { //檢查類,如果匹配就返回false val otherStudent=other as? Student ?:return false //在安全轉換之后,變量otherStudent被智能地轉換為Student類型 return otherStudent.firstName== firstName &&otherStudent.lastName== lastName } override fun hashCode(): Int =firstName.hashCode()*37+lastName.hashCode() } fun main(args: Array<String>) { val s1=Student("Alex","Wang") val s2=Student("Alex","Wang") println(s1==s2)//運算符會調用"equals"方法 println(s1.equals(s2)) println(s1.equals(42)) } ~~~ 運行結果 ``` true true false Process finished with exit code 0 ``` 使用這種模式,可以非常容易地檢查實參是否是適當的類型,轉換它,并在它的類型不正確時返回false ,而且這些操作全部在同一個表達式中。當然,這種場景下智能轉換也會生效:當你檢查過類型并拒絕了null 值,編譯器就確定了變量otherStudent值的類型是Student并讓你能夠相應地使用它。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看