官方文檔: http://kotlinlang.org/docs/reference/exceptions.html
1.異常類(Exception Classes)
與java類似,Kotlin的所有異常類都是Throwable類的子孫類(都繼承自Throwable類),
每個異常類成員都有消息(message),堆棧跟蹤(stack trace)和可選的起因(optional cause).
1.與Java一樣,kotlin使用throw表達(dá)式拋出異常(throw exception):
throw MyException("Hi There!")
2.與Java一樣,kotlin使用try表達(dá)式捕獲異常(catch exceptio):
try {
// 一些代碼
} catch (e: SomeException) {
// 處理程序
} finally {
// 可選的finally塊
}
//可以有零或多個catch塊,finally塊可省略,但catch和finally塊至少應(yīng)該存在一個!
3.與Java不同,kotlin的try表達(dá)式有一個返回值
try表達(dá)式返回值是try塊最后一個表達(dá)式,或者是catch塊最后一個表達(dá)式,
finally塊內(nèi)容不會影響表達(dá)式的結(jié)果.
fun main(args: Array<String>) {
val a: Int? = try {
1 //正常運(yùn)行,返回1
} catch (e: NumberFormatException) {
2
null
} finally {
3 //finally塊不會影響表達(dá)式結(jié)果
}
val b: Int? = try {
1
throw NumberFormatException()
} catch (e: NumberFormatException) {
2
null //捕獲異常,返回null
} finally {
3 //finally塊不會影響表達(dá)式結(jié)果
}
println(a) //輸出1
println(b) //輸出null
}
2.沒有受檢異常(Checked Exceptions)
java兩種異常類型: 受檢異常(checked exception)和非受檢異常(unchecked exception)
1.Error和RuntimeException及其子類都是非受檢異常(unchecked exception);
2.其余的異常Exception都是受檢異常(checked exception)茉稠。
這兩種異常在作用上沒有差別,唯一差別在于在編譯時編譯器會檢查受檢異常,
所以受檢異常需要try catch捕獲來避免編譯錯誤,而非受檢異常不需要!
可見受檢異常(Checked Exceptions)使用比較麻煩,爭議非常大,可能會導(dǎo)致java API變得很復(fù)雜,
程序跟異常檢查代碼混雜在一起,這僅僅是為了通過編譯器的編譯,
許多人批評Java的受檢異常,認(rèn)為受檢異常(Checked Exception)是軟件工程中一次失敗的試驗(yàn)!
kotlin沒有受檢異常(Checked Exceptions),以下是kotlin不使用受檢異常的原因描述:
JDK的StringBuilder類實(shí)現(xiàn)的一個示例接口:
Appendable append(CharSequence csq) throws IOException;
這個append函數(shù)簽名throws IOException,每次追加一個字符串(StringBuilder/某種日志log/控制臺console),
就必須捕獲IOException(可能正在執(zhí)行IO操作Writer也實(shí)現(xiàn)了Appendable),所以導(dǎo)致try{}代碼隨處可見:
try {
log.append(message)
} catch (IOException e) {
}
java受檢的異常(Checked Exception)很不好用,參見《Effective Java》第65條:不要忽略異常!
Bruce Eckel在《Java是否需要受檢的異常摘能?》Does Java need Checked Exceptions?中指出:
一些小程序測試得出的結(jié)論是:受檢的異常會提高開發(fā)者的生產(chǎn)力和代碼質(zhì)量高,
但是大型軟件項(xiàng)目的經(jīng)驗(yàn)有不同的結(jié)論:生產(chǎn)力降低,代碼質(zhì)量低或沒有提高!
其他相關(guān)引證:
《Java的受檢異常是一個錯誤》Java's checked exceptions were a mistake (Rod Waldhoff)
《受檢異常的煩惱》The Trouble with Checked Exceptions (Anders Hejlsberg)
3.Nothing類型(The Nothing type)
在Kotlin中throw是表達(dá)式,所以可以作為Elvis表達(dá)式?:的一部分:
val s = person.name ?: throw IllegalArgumentException("Name required")
throw表達(dá)式的類型是Nothing類型,該特殊類型沒有值,只用于標(biāo)記代碼位置永遠(yuǎn)不能到達(dá)(never be reached)
所以當(dāng)person.name為null時, s = 賦值操作永遠(yuǎn)不會發(fā)生(即throw類型Nothing,永遠(yuǎn)不可到達(dá)s = )
可以使用 Nothing 來標(biāo)記一個函數(shù)永遠(yuǎn)不會返回(never return):
fun main(args: Array<String>) {
fun fail(message: String): Nothing {
throw IllegalArgumentException(message)
}
//當(dāng)調(diào)用該函數(shù)fail()時,編譯器會知道執(zhí)行不會超出該調(diào)用(說白了就是程序不會繼續(xù)執(zhí)行)
//程序中斷,輸出 "java.lang.IllegalArgumentException: Name參數(shù)錯誤,不能為null"
val name = null
val s: String = name ?: fail("Name參數(shù)錯誤,不能為null")
println(s)
}
4.kotlin與Java互操作的異常處理(Java Interoperability)
在Kotlin中,所有異常都是非受檢的,意味著編譯器不會強(qiáng)迫捕獲任何異常(try catch)!
因此,在Kotlin中調(diào)用一個受檢異常的Java方法,不會強(qiáng)迫你去捕獲異常:
//kotlin代碼,調(diào)用java方法,append(CharSequence csq) throws IOException;
fun render(list: List<*>, to: Appendable) {
for (item in list) {
//在kotlin中不要求捕獲異常,但在Java中會強(qiáng)迫捕獲異常IOException
to.append(item.toString())
}
}
簡書:http://www.reibang.com/p/227f398b929f
CSDN博客: http://blog.csdn.net/qq_32115439/article/details/74617358
GitHub博客:http://lioil.win/2017/07/06/Kotlin-exception.html
Coding博客:http://c.lioil.win/2017/07/06/Kotlin-exception.html