日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網(wǎng)站首頁 編程語言 正文

Kotlin中空判斷處理操作實例_Android

作者:android_cai_niao ? 更新時間: 2022-09-23 編程語言

Kotlin中的一個偉大創(chuàng)前舉就是空指針的處理,在代碼的編譯階段就能檢測可能出現(xiàn)的空指針問題,示例代碼如下:

data class Person(var name: String? = null)

fun sayHello(name: String) {
    println("Hello $name")
}

fun main() {
    val person = Person("Even")
    if (person.name != null) {
        sayHello(person.name)
    }
}

在IntelliJ中,如上代碼會報錯,如下:

提示的錯誤信息翻譯為:智能強制轉(zhuǎn)換為’String’是不可能的,因為’person.name’是一個可變屬性,此時可能已經(jīng)被更改了。

要想編譯通過,需要這樣做:

sayHello(person.name!!)

哎?我記得學Kotlin的時候有解釋說如果已經(jīng)判斷了不是空了的話,就不需要添加 !! 符號的,為什么這里不添加的話會報錯呢?其實原因就是報錯信息上提示的,因為name是用var修飾的,而且這是一個成員變量,雖然你做了非空的判斷,但是判斷之后,這個成員屬性有可能在其它線程被修改了,比如在其他線程設置為null了,所以,這樣的話就會出現(xiàn)空指針異常了,所以添加 !! 符號來解決報錯不是最佳實踐,在我這個示例中,我們知道沒有開多線程去修改person的name屬性,所以可以加 !! 來解決,但是最好不要這樣做,如果我們知道name屬性不會被修改,則可以使用val修飾,如下:

可以看到,此時不需要添加 !! 也不報錯了,因為IDE知道name是一個不可變屬性,判斷了不是空之后,就永遠不可能是空了。

有時候,name屬性就需要發(fā)生變化,就必須聲明為var,此時怎么解決呢?,可以通過添加局部變量解決,如下:

如上代碼,IDE沒有報錯。我們通過添加一個val類型的name局部變量來保存person.name的值,這樣的話,判斷了name為不為空之后,即使person.name在子線程被設置為空了,但是局部變量name不會受到影響。我們在閱讀一些系統(tǒng)源碼的時候,不論是Java源碼或是Kotlin的源碼,經(jīng)常發(fā)現(xiàn)別人在判斷一個對象的屬性的可空性的時候,都是先聲明一個局部變量保存該對象屬性再來判斷,不懂事的時候就會奇怪別人為什么要多此一舉,現(xiàn)在明白了,別人是為了預防直接判斷對象屬性出現(xiàn)的多線程修改帶來的問題。

添加局部變量的話,即使是var類型的局部變量IDE也能判斷是否為空,示例如下:

如上代碼,可以看到,局部變量name是可變類型的,但是也不需要添加 !! 符號,因為var類型的局部變量不會被子線程修改,所以判斷了不為空之后就不會為空。最后賦值了”Lily“,然后傳給sayHello(name),這里并沒有做非空判斷啊,sayHello接受的是不可空的String,但是name是一個可空String啊,道理也很簡單,因為這是局部變量,沒有子線程的干擾,IDE能檢測到name在傳給sayHello之前是賦值了”Lily"的,之后沒有再賦值為null也是能檢測出來的,所以這里不需要做可空判斷也能編譯通過。如果沒有賦值“Lily",則IDE就不知道name是否為空了,就會報錯,如下:

或者,如果我們使用的是一個成員變量,即使前一句代碼賦值了下一句就用也是會報錯的,原因就是它有可能在子線程被設置為null了,如下:

所以,Kotlin是真的很強,如果你在使用一個變量,只要IDE沒報錯,你就可以放心的使用,不需要做空判斷,你可以放心,運行時不會有空指針問題的。如果IDE報錯了,就是有可能發(fā)生空指針的,此時你就不要強制添加 !! 來逃避問題了,一定要做合理的空指針判斷處理。如果你使用Java的話,要不要做空指針處理IDE是沒有提示的,你只能自己用腦子去想要不要做空指針判斷處理,事實往往是我們根本就不去想要不要做處理,或者即使思考過了,也會有思考出錯的時候,比如可能出現(xiàn)空指針的地方,但是你寫代碼時你認為不會出現(xiàn)空指針,所以你沒做非空判斷處理,則運行時就有可能出現(xiàn)空指針異常了。而Kotlin就會有提示,只要IDE沒報錯就不用做空指針處理,只要IDE報錯了就要做空指針處理,這真是爽歪歪啊,你不需要去思考什么時候應該添加空指針判斷處理了!

注:這個可空判斷也適用于類型智能轉(zhuǎn)換,這個知識點在官網(wǎng)教程上也找到了答案:https://kotlinlang.org/docs/typecasts.html#unsafe-cast-operator,相關內(nèi)容如下:

Note that smart casts work only when the compiler can guarantee that the variable won’t change between the check and the usage. More specifically, smart casts can be used under the following conditions:

val local variables - always, with the exception of local delegated properties.

val properties - if the property is private or internal or if the check is performed in the same module where the property is declared. Smart casts cannot be used on open properties or properties that have custom getters.

var local variables - if the variable is not modified between the check and the usage, is not captured in a lambda that modifies it, and is not a local delegated property.

var properties - never, because the variable can be modified at any time by other code.

附:?.和!!.

其實kotlin是非常人性話的,你定義了一個可為空的變量但是你依然可以去操作的。我們修改一下上面的寫法:

val a:String = "我加小明"
val b:String ?= null
val c:String? = "我加小明"

? println(a.length)
? println(b?.length)
? ?println(c!!.length)

這樣編譯就通過。

這里的**?.**就是相當于Java的如果為空就返回null 而kotlin強制讓我們?nèi)ヌ幚?,這樣就避免了很多空指針異常

if(b==null) return null;

當然如果你不想直接為null,你說當為空時我想自己去處理,kotlin還有語法**?:**

val b:String ?= null
 println(b?.length?:"我錯了")

!!. 表示我任性,告訴編譯器不要去做非空檢查,為空就拋異常

總結(jié)

原文鏈接:https://blog.csdn.net/android_cai_niao/article/details/120760577

欄目分類
最近更新