Kotlin入門筆記三:可空型別
這次文章給大家介紹下Kotlin中的可空型別,說起可空這個問題,那就不得不提空指標異常啦,大家在開發中肯定被空指標折磨的不要不要的。筆者在實習期間可是被空指標困擾了很長時間,動不動APP就Crash掉了,開啟Log一看,java.lang.NullPointerException
就出現在眼前,接著就開始了漫長的非空判斷。
但是在kotlin中,這種現象得到了很好的控制,kotlin引入了可空型別,給開發者帶來了完美的解決方案,下面就來學習學習一下kotlin中可空型別。
1.可空型別的變數
kotlin中可以直接將一個變數宣告為可空型別,允許它為空,並且加入了很多的運算子,我們來一一學習:
首先我們來看看java中常規的判斷一個字串是否為空的寫法:
public class MyNull {
public static void main(String[] args) {
checkStringNull("");
}
private static String checkStringNull(String string) {
return string == null ? "null" : string;
}
}
// 輸出:null
再來對比下kotlin對可空變數的處理
fun main(args: Array< String>) {
var string: String?
string = null;
println(checkStringNull(string))
}
fun checkStringNull(string: String?): String? {
return string
}
// 輸出:null
這裡我們首先看到函式傳了一個String
型別的引數,並且String
後面多了一個?
,這就是kotlin的可空型別的宣告,它無需再像java那樣判斷是否為空,kotlin這種是允許為空,在宣告過後,這個變數就預設儲存了一個null
引用,如果這個變數為空的話,就會取出這個null
?
修飾的變數是預設不可為空的。
2.安全呼叫運算子:"?:"
上面我們知道了如何宣告一個可空型別的變數,接著我們來看看如何運用這個可空變數:
我們通過一個例子來欣賞下安全呼叫運算子的強大之處:java版和kotlin版的小寫轉大寫
java:
public class MyNull {
public static void main(String[] args) {
String string = null;
stringToUpperCase(string);
}
private static String stringToUpperCase(String string) {
return string.toUpperCase();
}
}
輸出結果
// AAA
// Exception in thread "main" java.lang.NullPointerException
// at MyNull.stringToUpperCase(MyNull.java:10)
// at MyNull.main(MyNull.java:6)
很明顯,在stringToUpperCase
方法中沒有對string
進行非空判斷,導致NullPointerException
的異常丟擲。
kotlin:
fun main(args: Array<String>) {
val string: String? = "aaa"
val nullString: String? = null
println(stringToUpperCase(string))
println(stringToUpperCase(nullString))
}
fun stringToUpperCase(string: String?): String? {
return string?.toUpperCase()
}
輸出結果:
// AAA
// null
kotlin卻沒有丟擲異常,而是返回了null
,是不是很驚訝kotlin的強大,讓我們來看看kotlin的安全運算子是如何處理的:
只有當String
不為空時,才會呼叫toUpperCase
方法,String
為空的時候,直接返回了null
,這下媽媽再也不怕我們忘記處理空指標的情況了,哈哈~~
3.Elvis運算子:"?:"
在日常開發中我們也許會遇到這麼一個需求:如果介面返回的資料為空,顯示為“–”。這就得對資料為空的情況額外處理了,我們還是對比java和kotlin的做法:
java
public class MyNull {
public static void main(String[] args) {
String string = "aaa";
String nullString = null;
System.out.println(checkStringNull(string));
System.out.println(checkStringNull(nullString));
}
private static String checkStringNull(String string) {
return string == null ? "--" : string;
}
}
輸出結果:
// aaa
// --
java中我們可以使用三元運算子來判斷是否為空,然後處理,這算是比較簡潔的寫法了,再來看看kotlin是否更簡單。
kotlin
fun main(args: Array<String>) {
val string: String? = "aaa"
val nullString: String? = null
println(checkStringNull(string))
println(checkStringNull(nullString))
}
fun checkStringNull(string: String?): String? {
return string ?: "--"
}
輸出結果:
// aaa
// --
對比之下,kotlin程式碼貌似更簡單了呢,同時也出現了新的運算子,它就是:"?:" Elvis運算子,用來替代null
這種預設值的情況。
結合著這張圖,我們來看看**"?:"**是如何處理的,bar
是用來代替預設值null
的,如果foo==null
,那麼就直接返回bar
,和java中string == null ? "--" : string;
三元運算子作用類似。
4.非空斷言:"!!"
kotlin還提供了一個運算子,如果你確定你的變數不可能為空,那麼就可以使用**!!**來修飾你的變數,這種情況下,如果你的變量出現了null
的情況,就會丟擲空指標異常,我們來通過程式碼感受下:
fun main(args: Array<String>) {
val string: String? = "aaa"
val nullString: String? = null
println(sureNotNull(string))
println(sureNotNull(nullString))
}
fun sureNotNull(string: String?): String? {
return string!!
}
輸出結果:
// Exception in thread "main" aaa
// kotlin.KotlinNullPointerException
// at MyNullKt.sureNotNull(MyNull.kt:9)
// at MyNullKt.main(MyNull.kt:5)
非空斷言要謹慎使用哦,別斷著斷著你的程式就crash掉了…
這期就給大家帶來這麼多,看完是不是覺得kotlin對開發者友好很多,有了可空型別的變數,我們就不必對介面返回的資料一一就行非空判斷了。下期筆者將為大家介紹下kotlin中的集合。
寫在最後
每個人不是天生就強大,你若不努力,如何證明自己,加油!
Thank You!
–Taonce