用途
為什麼要例外處理呢? 因為在處理某些程式時,有可能會出現runtime error,比如 var i=”1234cm”.toInt(),就會因為無法轉成整數而造成程式閃退。所以就在可能出錯的地方,使用 try-catch將之包含起來。當發生錯誤後,就會跳到catch區塊。
fun main(args:Array<String>){
try{
var i="1234a".toInt()
println(i)
}
catch(e:Exception){
println(e.message)
}
}
catch參數
catch參數跟kotlin函數一樣,都是常數,所以不可加var
try { println(a / b) } catch (vare :Exception ){//不可加var print(e.message) }
finally
try-catch的最後區塊為finally,不論是否有發生例外,finally都會被執行
fun main(args:Array<String>){
try{
println("開始轉換了")
var i="1234".toInt()
println("i=$i")
}
catch(e:Exception){
println(e.message)
}
finally{
println("執行finally")
}
}
結果:
開始轉換了
i=1234
執行finally
返回值
kotlin很喜歡有返回值的語法。如下代碼,可返回區塊內的最後一個表達式。而且不受finally區塊影響
fun main(args:Array<String>){
var i=
try{
println("開始轉換了")
"1234".toInt()
}
catch(e:Exception){
println("轉換失敗")
0
}
finally{
println("執行finally")
100
}
println(i)
}
結果:
開始轉換了
執行finally
1234
多catch
例外處理可以有多個catch。Java有規定必需先catch子類別,然後再catch父類別。kotlin並沒有這個規定,但還是要遵守,否則會抓到不準確的例外,如下所示
fun main(args:Array<String>){
try{
var a:Array<String> = Array(10, {""})
a[10]="abcd"
}
catch(e:Exception){
println("Exception 錯誤")
}
catch(e: ArrayIndexOutOfBoundsException){
println("超出範圍")
}
}
結果:
Exception 錯誤
Checked/Unchecked
在Java中,例外有Checked(已檢查)及Unchecked(未檢查) 二種Exception。比如FileNotFoundException這種Checked時,就規定一定要寫try-catch。但如果是ArithmaticException這種除到0的錯誤,則交由程式設計師自已決定要不要寫try-catch。
在kotlin裏,全部都是Unchecked Exception,全交由程式設計師自己決定。當然這就可能因程式設計師疏忽造成RuntimeError,導致程式閃退。關於這一點,kotlin官網只說是為了提高程式的可讀性,其他就沒再多說明了。
Checked Exception的存在與否,是一個很大的學術理論。大部份的理論都建議 Java 應該要取消CE,所以連C#都沒有CE。不過試想一事,如果明確知道代碼中不可能會出現錯誤,但卻因為CE關係所以一定要寫try-catch,這真的會讓程式碼變得很難閱讀。
拋出例外
拋出例外可以使用throw關鍵字,如 throw(Exception(“訊息”))。
請注意,如果是在次建構子拋出例外的話,那就不會返回物件,而是null值
fun main(args:Array<String>){
var p1:Pokemon?=null
try {
p1 = Pokemon()
}
catch(e:Exception ){
println(e.message)
if(p1==null)println("p1 為 null")
else println("p1 不是 null")
}
}
class Pokemon{
constructor(){
if (Math.random()<0.5)println("Pokemon出生了")
else throw(Exception("Pokemon流產了"))
}
}
結果:
Pokemon流產了
p1 為 null