天天看點

Kotlin-22-null安全的實作

目錄

1、對null的約定

2、Java中對null值處理

3、Kotlin中 null安全的實作

4、Kotlin的null異常報錯

1、對null的約定

 kotlin對變量的null進行了區分 
var name: String = "Zhang San" //為不可null的變量
var name1: String? = null      //為可null的變量
var name2: String = null       //報錯
           
  相同資料類型的可null和不可null的兩個變量是兩種完全不同的類型的變量
  •   1、它們之間不能直接互相指派
  •   2、不可null和可null的兩種類型之間的轉換類似于int和float                                                                                                                     (可null是不可null的進階類型)   
private fun testNull(){
    name=name1     //1、報錯,不可null的變量不能直接轉換為可null
    name=name1!!   //2、可以加兩個感歎号進行類型強轉
    name1=name     //3、不可null可的變量可以隐式轉換為可null
}
           

2、Java中對null值處理

java中對null的處理是給了我們兩個注解:
@NotNull 被注解的變量不能指派為null,當指派為null的時候會給出黃色的警告
@Nullable 被注解的變量可以      

注意:這些注解隻會在我們書寫代碼的時候,給我們一個黃色警告,來讓我們避免的錯誤的指派為null,但是當我們不小心傳了一個null的時候他們在運作的時候是會報錯的,但是在Kotlin,你如果聲明該類型為可null,則不會報錯。

左邊是我們的源碼,右邊是編譯後的class檔案,明顯看出,這兩個注解隻是警告作用,并沒有實際的判null操作。

Kotlin-22-null安全的實作
Kotlin-22-null安全的實作

我們看到上面代碼中,我們對變量name2和printNam()函數的參數都用@NotNull 進行了注解,在我們給它們指派為null的時候,會給我們一個黃色的警告,并且會給我們說明。但是我們強行運作這段代碼的時候,它是會直接報錯的。

而用了@Nullable 注解的pringName1()函數的參數時,它會警告我們讓我們對str進行if null值的判斷。

Kotlin-22-null安全的實作

3、Kotlin中 null安全的實作

null安全的實作其實就是對你聲明的變量進行兩步null判斷處理,下面有源碼解釋:

第一步:給你變量加上@Nullable @NotNull 注解,讓你的在書寫代碼的時候就減少指派null的錯誤情況

第二步:在編譯代碼之後會自動給你的的變量進行null值判斷。

下面左邊是我們的源碼,右邊是編譯成class檔案之後我們反編譯得到的源碼,如果想看反編譯kotlin檔案,可以看這裡:Kotlin-20-如何檢視Kotlin編譯成class後的代碼。

從反編譯的源碼中我們看到,當我們聲明一個可null的變量 name1時,它不僅會給我們添加上@Nullable的注解,讓我們在書寫代碼的時候就盡量避免指派錯誤,更重要的時候,綠色框中,在編譯後,它會自動幫我們添加對參數可null的判斷,這樣在運作的時候就不會再報錯。

而當我們中聲明一個變量為不可null的時候,因為我們在聲明指派階段,就不會造成null的情況,是以運作代碼的時候,一般是不會報錯的,除非有一種情況會報錯--->看第4節

Kotlin-22-null安全的實作
Kotlin-22-null安全的實作
Kotlin-22-null安全的實作

 輸出結果:

0
null
           

4、Kotlin的null異常報錯

上面我們講了 可null的參數,編譯之後會自動添加判null操作,而不可null的參數,又在聲明的時候無法指派為null,那怎麼樣才會出現null異常呢?

當調用Java中的null對象輸出的時候會報錯。
//java中的代碼
public class TestNull {
    String name="";
    @Nullable
    String name1=null;
    @NotNull
    String name2=null;
}

//Kotlin中的代碼
fun printName(str: String) {
    println(str.length)
}
fun printName1(str: String?) {
    println(str?.length)
}
fun main() {
    val test= TestNull()

    printName1(test.name2)
    printName(test.name2)
  //  printName(test.name1)  ---報錯 因為name1是可null類型,無法指派到不可null類型上。
}
           

輸出結果:

Kotlin-22-null安全的實作
從輸出結果看出pringName1 對null做了處理,是以不會報錯,但是Kotlin中對不可null類型隻是進行了抛出異常的處理,并沒有做其他處理,是以這樣在調用Java的null值時還是會報錯。