Kotlin-33.異常(Exception)

官方文檔: 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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末刻盐,一起剝皮案震驚了整個濱河市谢床,隨后出現(xiàn)的幾起案子鹦马,更是在濱河造成了極大的恐慌淋袖,老刑警劉巖悼凑,帶你破解...
    沈念sama閱讀 223,002評論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件罚屋,死亡現(xiàn)場離奇詭異晦炊,居然都是意外死亡鞠鲜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評論 3 400
  • 文/潘曉璐 我一進(jìn)店門断国,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贤姆,“玉大人,你說我怎么就攤上這事稳衬∠技瘢” “怎么了?”我有些...
    開封第一講書人閱讀 169,787評論 0 365
  • 文/不壞的土叔 我叫張陵薄疚,是天一觀的道長碧信。 經(jīng)常有香客問我,道長街夭,這世上最難降的妖魔是什么砰碴? 我笑而不...
    開封第一講書人閱讀 60,237評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮板丽,結(jié)果婚禮上呈枉,老公的妹妹穿的比我還像新娘。我一直安慰自己檐什,他們只是感情好碴卧,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,237評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著乃正,像睡著了一般。 火紅的嫁衣襯著肌膚如雪婶博。 梳的紋絲不亂的頭發(fā)上瓮具,一...
    開封第一講書人閱讀 52,821評論 1 314
  • 那天,我揣著相機(jī)與錄音凡人,去河邊找鬼名党。 笑死,一個胖子當(dāng)著我的面吹牛挠轴,可吹牛的內(nèi)容都是我干的传睹。 我是一名探鬼主播,決...
    沈念sama閱讀 41,236評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼岸晦,長吁一口氣:“原來是場噩夢啊……” “哼欧啤!你這毒婦竟也來了睛藻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,196評論 0 277
  • 序言:老撾萬榮一對情侶失蹤邢隧,失蹤者是張志新(化名)和其女友劉穎店印,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體倒慧,經(jīng)...
    沈念sama閱讀 46,716評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡按摘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,794評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了纫谅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片炫贤。...
    茶點(diǎn)故事閱讀 40,928評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖付秕,靈堂內(nèi)的尸體忽然破棺而出照激,到底是詐尸還是另有隱情,我是刑警寧澤盹牧,帶...
    沈念sama閱讀 36,583評論 5 351
  • 正文 年R本政府宣布俩垃,位于F島的核電站,受9級特大地震影響汰寓,放射性物質(zhì)發(fā)生泄漏口柳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,264評論 3 336
  • 文/蒙蒙 一有滑、第九天 我趴在偏房一處隱蔽的房頂上張望跃闹。 院中可真熱鬧,春花似錦毛好、人聲如沸望艺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽找默。三九已至,卻和暖如春吼驶,著一層夾襖步出監(jiān)牢的瞬間惩激,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評論 1 274
  • 我被黑心中介騙來泰國打工蟹演, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留风钻,地道東北人。 一個月前我還...
    沈念sama閱讀 49,378評論 3 379
  • 正文 我出身青樓酒请,卻偏偏與公主長得像骡技,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子羞反,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,937評論 2 361

推薦閱讀更多精彩內(nèi)容