背景
既然Google官方已經(jīng)宣布Kotlin為Android官方語言,我覺得,那就沒什么可爭議的,作為Android開發(fā)者必須開始學習,跟上節(jié)奏,相信不會很費力氣。我學習的大部分知識來自Kotlin 學習之路,這哥們寫得非常細心,真心贊。
Kotlin如何減少空指針異常
首先科普一下什么情況會導(dǎo)致NPE(空指針異常):
String str; //聲明變量
//str="Hello Word"; //沒有初始化變量
str.hashCode(); //報NPE
Kotlin 解決空安全,不是消滅 NPE,而是 允許 NPE 存在,但只會在它該出現(xiàn)的地方出現(xiàn) 。
可空類型與非空類型
所有數(shù)據(jù)類型默認都是非空(non-null)的,如果想把 null 賦給它們的對象,需要在類型后加上 ? ,聲明為可空類型。Kotlin 這樣設(shè)計有什么好處呢?我們只要將變量聲明為非空類型,就可以放心地調(diào)用它的實例方法和實例變量,不用擔心出現(xiàn) NPE。
val str:String="Hello World"; //不可空類型
val str:String?=null; //可空類型
如何安全地調(diào)用可空類型變量的方法
上面講到我們可以放心地調(diào)用非空類型變量的方法,可對于可空類型呢?要用到以下方法:
val str:String?=null; //可空類型
//str="Hello World";
str.?hashCode();
如果 ?. 前的對象不為 null,則調(diào)用 ?. 后的方法或?qū)傩?,否則返回 null。
Elvis 操作符 ?:
比如這段 Java 代碼:
File[] files = new File("C:\\Documents").listFiles();
System.out.println((files != null) ? files.length : "Empty");
如果 files 數(shù)組為 null,則打印 "Empty",如果不為 null,則打印數(shù)組的長度。
用 Kotlin 寫是這樣的:
val files = File("C:\\Documents").listFiles()
println(files?.size ?: "Empty")
可以這樣理解 Kotlin 里的 Elvis 操作符:
A ?: B 等價于 if(A == null) B
A?.B ?: C 等價于 if(A != null) A.B else C
let 函數(shù)
Java寫法:
File[] files = (new File("C:\\Documents")).listFiles();
if(files != null) {
for(int i = 0; i < files.length; i++) {
File file = files[i];
System.out.println(file.getName());
}
}
Kotlin寫法:
val files = File("C:\\Documents").listFiles()
// files 的類型自動推斷為 Array<File>?
files?.let {
for (file in files)
println(file.name)
}
相比上面的.?,這個?.let只是多了個括號。
非空操作符 !!
Kotlin寫法:
val files = File("C:\\Documents").listFiles()!! // files 的類型自動推斷為 Array<File>
for(file in files)
println(file.name)
Java寫法:
File[] var1 = (new File("C:\\Documents")).listFiles();
if(var1 == null)
Intrinsics.throwNpe(); // 拋出 NPE
File[] files = var1;
也就是說加了!!的地方,如果為null,則會報NPE,所以說Kotlin還是存在空指針異常的,只不過Kotlin官方不建議代碼中有太多的!!,否則就浪費了Kotlin設(shè)計良好的非空類型。
總結(jié)
我把一個用Java寫的項目全改成Kotlin了,發(fā)覺原來的項目里存在太多會出現(xiàn)NPE的地方,而這些地方往往在我們寫代碼、測試時是無法發(fā)現(xiàn)的,只有在生產(chǎn)環(huán)境下,看后臺的log才發(fā)現(xiàn)這些問題,所以Kotlin這個設(shè)計還是非常棒的!
寫著寫著,心里有些糾結(jié),本著自己消化總結(jié)后寫一篇通俗易懂的,可是后來發(fā)現(xiàn)原文寫得太好了,糾結(jié)糾結(jié),再次感謝作者,附上原文鏈接吧!