空安全
因為在kotlin中,默認的類中是無法用null進行初始化,所以可能出現NPE的范圍大大縮小了。
var s: String = null
這樣的語句是無法通過編譯的。可能出現NPE的地方官網已經為我們說明:
- 顯式調用 throw NullPointerException()
- 使用了下文描述的 !! 操作符
- 外部 Java 代碼導致的
- 對于初始化,有一些數據不一致(如一個未初始化的 this 用于構造函數的某個地方)
對一些屬性而言,我們希望在合理的地方進行初始化,變會有了如下的語句:
var s: String? = null
對s調用可以使用以下方法處理
- !!
s!!.length
在java中它就是
if(s!=null){
return s.length
}else {
throw new NullPointerException()
}
- ?.
s?.length
在java中它就是
if(s!=null){
return s.length
}else {
return null
}
-Elvis 操作符
s?.length ?: -1
這句可以分為 A ?: B
,只有在A=null時,執行B
同時因為 throw 和 return 在 Kotlin 中都是表達式,所以它們也可以用在 elvis 操作符右側。這可能會非常方便,例如,檢查函數參數:
fun foo(node: Node): String? {
val parent = node.getParent() ?: return null
val name = node.getName() ?: throw IllegalArgumentException("name expected")
// ……
}
異常
kotlin中拋出異常使用throw Excetion(msg: String)
,同時使用try-catch-finally模塊捕獲異常,可以有零到多個 catch 塊。finally 塊可以省略。 但是 catch 和 finally 塊至少應該存在一個。
不同于java,kotlin中的try是一個表達式,可以得到返回值,try-表達式的返回值是 try 塊中的 最后一個表達式或者是(所有)catch 塊中的最后一個表達式。 finally 塊中的內容不會影響表達式的結果。
val a: Int? = try { parseInt(input) } catch (e: NumberFormatException) { null }
java中對異常會強制開發人員try-catch或throw,這里則不強制開發人員去處理異常(Rhett:可能我理解不夠深,我還是覺得java的處理方式比較好)。
Nothing類
在 Kotlin 中 throw 是表達式,所以你可以使用它(比如)作為 Elvis 表達式的一部分:
val s = person.name ?: throw IllegalArgumentException("Name required")
throw 表達式的類型是特殊類型 Nothing。 該類型沒有值,而是用于標記永遠不能達到的代碼位置。 在你自己的代碼中,你可以使用 Nothing 來標記一個永遠不會返回的函數:
throw IllegalArgumentException(message)
}
當你調用該函數時,編譯器會知道執行不會超出該調用:
println(s) //能達到這里說明s初始化已經完成