(1)空類型安全的概念
注意,在這裏nonNull重新賦值爲null的時候,編譯會報錯。這是因爲前面聲明的nonNull爲String類型,在Kotlin中String類型爲非空類型,所以當再給nonNull賦值爲null的時候,編譯會報錯。
如果想使nonNull可以賦值爲null,怎麼辦呢?如下操作:
var nonNull:String?="Hello"
nonNull=null
在聲明的時候,在類型後面加問號?,意爲變量可以爲空。
但是這樣寫,在使用時有可能報空指針:
可以強轉爲不可空類型:
val length=nonNull!!.length
但是這種形式是在確定nonNull不爲空的情況下,可以這樣用,如果nonNull爲空,那麼在運行時還會報空指針異常,不夠安全。
那麼如何安全地書寫呢?看下面這種形式:
val length=nonNull?.length
這種書寫形式,無論nonNull是不是空,都不會觸發空指針。只是在nonNull不爲空的時候,val length=nonNull.length;在nonNull爲空的時候,val length=null;
但是這種形式也有一種弊端,就是length可能爲Int類型,也可能爲null類型。爲了使length的類型能夠統一,我們可以這樣寫:
val length=nonNull?.length?:0 //elvis運算符
這種形式,意爲如果nonNull不爲空,那麼val length=nonNull.length,如果nonNull爲空,那麼val length=0;
這樣不僅保證了nonNull不會報空指針,而且保證了length的類型統一。
(2)空類型的繼承關係
var x:String="Hello"
var y:String?="World"
y=x//編譯成功
var x:String="Hello"
var y:String?="World"
x=y//編譯失敗
說明了String是String?的子集
裏式替換原則:任何基類出現的地方,子類一定可以出現。
(3)平臺類型
Java、JavaScript、Native
不同語言之間的調用,比如Kotlin調用Java中的代碼,這時需要開發者注意,判斷是否爲空,例如:
在Kotlin中定義的這個title,編譯器無法判斷是否有可能爲空。如果開發者不注意,那麼當title爲空的情況下去執行title.length就會報空指針。
也可以用@NotNull註解進行一下約束,但是添加了@NotNull註解的方法就不能反回null了: