譯文《最常見(jiàn)的10種Java異常問(wèn)題》

封面:洛小汐

譯者:潘潘

封面圖

知彼知己,方能百戰(zhàn)不殆。

前言

本文總結(jié)了有關(guān)Java異常的十大常見(jiàn)問(wèn)題。

目錄

  1. 檢查型異常(checked) vs. 非檢查型異常(Unchecked)

  2. 異常管理的最佳實(shí)踐箴言

  3. 為什么在try代碼塊中聲明的變量不能在catch或者finally中被引用?

  4. 為什么 Double.parseDouble(null) 和 Integer.parseInt(null) 拋出的異常不一樣呢?

  5. Java中經(jīng)常使用的運(yùn)行時(shí)異常

  6. 我們可以在同一個(gè)catch子句中捕獲多個(gè)異常嗎爆袍?

  7. 在 Java 中構(gòu)造方法能拋出異常嗎首繁?

  8. 在 final 代碼塊中拋出異常

  9. try語(yǔ)句有return那么finally還會(huì)執(zhí)行嗎?

  10. 為何有些開(kāi)發(fā)人員對(duì)異常置之不理陨囊?

檢查型異常(checked) vs. 非檢查型異常(Unchecked)

簡(jiǎn)單來(lái)說(shuō)弦疮,對(duì)于檢查型異常, 一般在 編譯期 就會(huì)被檢查到蜘醋,所以我們肯定會(huì)提前在方法內(nèi)進(jìn)行捕獲處理胁塞,或者在方法頭部申明并拋出。而非檢查型異常压语,往往無(wú)法提前預(yù)知啸罢,例如被除數(shù)是0、空指針等胎食。檢查型異常特別重要扰才,它會(huì)告訴那些調(diào)用你的接口的開(kāi)發(fā)者們,如何提前預(yù)知并處理好這些可能發(fā)生的異常厕怜。

例如衩匣,IOException就是常見(jiàn)的檢查型異常,而 RuntimeException(運(yùn)行時(shí)異常)就是非檢查型異常粥航。在閱讀剩余部分之前你或許可以研讀這份 Java異常的層次結(jié)構(gòu)圖琅捏。

Java異常層次結(jié)構(gòu)圖
異常管理的最佳實(shí)踐箴言

如果可以正確處理異常,則應(yīng)將其捕獲并處理递雀,否則應(yīng)將其拋出柄延。

為什么在try代碼塊中聲明的變量不能在catch或者finally中被引用?

看下面這段代碼缀程,在try代碼塊中聲明的 String s 就不能在catch中被引用搜吧, 這段代碼在編譯期是通不過(guò)的。


try {
    File file = new File("path");
    FileInputStream fis = new FileInputStream(file);
    String s = "inside";
} catch (FileNotFoundException e) {
    e.printStackTrace();
    System.out.println(s);
}

原因是你不知道在try代碼塊中哪個(gè)位置會(huì)引發(fā)異常杠输, 很有可能在聲明對(duì)象之前就引發(fā)了異常赎败。對(duì)于這個(gè)特定的示例秕衙,是正確的蠢甲。

為什么 Double.parseDouble(null) 和 Integer.parseInt(null) 拋出的異常不一樣呢?

它倆拋出的異常確實(shí)不同据忘,但這是JDK的問(wèn)題鹦牛,當(dāng)時(shí)開(kāi)發(fā)這兩個(gè)接口的開(kāi)發(fā)人員不是同一波,所以我們沒(méi)必要去糾結(jié)這個(gè)問(wèn)題勇吊。


Integer.parseInt(null); 
// throws java.lang.NumberFormatException: null 

Double.parseDouble(null); 
// throws java.lang.NullPointerException

Java中經(jīng)常使用的運(yùn)行時(shí)異常

這里列舉一部分:

IllegalArgumentException
ArrayIndexOutOfBoundsException

在有些場(chǎng)景某個(gè)目標(biāo)對(duì)象不滿足我們的預(yù)期曼追,會(huì)用到這些異常,例如下面在 if 判斷語(yǔ)句中被使用:


if (obj == null) {
   throw new IllegalArgumentException("obj can not be null");

我們可以在同一個(gè)catch子句中捕獲多個(gè)異常嗎汉规?

答案是當(dāng)然可以礼殊,不過(guò)如果在同一個(gè)catch子句中捕獲的這些異常都直接或間接繼承自同一父類(lèi)驹吮,那么就只能在catch子句中捕獲父類(lèi)了。

// Java 7 之前需要這樣
catch (AException a) {
     logger.error(a);
     throw new MyException("a");
catch (BException b) {
     logger.error(b);
     throw new MyException("b");
}catch (CException c) {
     logger.error(c);
     throw new MyException("c");
}

// 在Java 7中晶伦,可以捕獲所有這些異常 
catch(AException | BException | CException ex){
     logger.error(ex);
     throw new MyException(ex);
}

補(bǔ)充說(shuō)明 : 其實(shí)是這樣碟狞,在 Java7 就開(kāi)始支持catch子句捕獲多個(gè)異常,多個(gè)異常使用 XOR符號(hào)(I)連接婚陪,異常的發(fā)生有可能是 A | B族沃,但不能同時(shí)出現(xiàn),相當(dāng)于這些異常不能是間接或直接繼承自同一個(gè)父類(lèi)泌参,因?yàn)槿绻鸄B都繼承同一父類(lèi)脆淹,那就不能 A|B 都寫(xiě)上,這也是繼承原則沽一。

在 Java 中構(gòu)造方法能拋出異常嗎盖溺?

答案是當(dāng)然可以,構(gòu)造方法僅是一種特殊方法而已铣缠「拦瘢可以參考這個(gè)示例

在 final 代碼塊中拋出異常

下面這個(gè)寫(xiě)法是合法的:


public static void main(String[] args) {
    File file1 = new File("path1");
    File file2 = new File("path2");
    try {
 
        FileInputStream fis = new FileInputStream(file1);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        try {
            FileInputStream fis = new FileInputStream(file2);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

但是為了獲得更好的代碼可讀性攘残,你應(yīng)該將把 try-catch代碼塊封裝成一個(gè)新方法拙友,然后將方法調(diào)用放在finally子句中:


public static void main(String[] args) {
    File file1 = new File("path1");
    File file2 = new File("path2");
    try {
 
        FileInputStream fis = new FileInputStream(file1);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        // 封裝方法
        methodThrowException(); 
    }
}

try語(yǔ)句有return那么finally還會(huì)執(zhí)行嗎?

答案是肯定會(huì)執(zhí)行歼郭。

Java官方文檔描述:The finally block always executes when the try block exits

意思就是 ” 只要存在try代碼塊遗契,finally代碼塊就一定會(huì)執(zhí)行 ” ,這種特性可以讓程序員避免在try語(yǔ)句中使用return, continue或者break關(guān)鍵字而忽略了關(guān)閉相關(guān)資源的操作等病曾。

為何有些開(kāi)發(fā)人員對(duì)異常置之不理牍蜂?

很多時(shí)候會(huì)見(jiàn)到下面這種代碼寫(xiě)法。允許的情況下盡可能捕獲異常并且進(jìn)行處理泰涂,不知道為什么很多開(kāi)發(fā)人員就是這么干鲫竞?


try {
     ...
} catch(Exception e) {
     e.printStackTrace();
}

忽略異常是一件很容易做到的事,雖然這種寫(xiě)法很常見(jiàn)逼蒙,但不一定是正確的寫(xiě)法从绘。

參考文獻(xiàn):
  1. Unchecked exceptions in Java
  2. The root of Java exception class hierarchy
  3. Java exceptions related questions in stackoverflow

譯文完,由于個(gè)人理解能力和知識(shí)寬度有限是牢,譯文中存在失誤之處僵井,還請(qǐng)見(jiàn)諒,歡迎指正驳棱。

BIU ~ 文章持續(xù)更新批什,微信搜索「潘潘和他的朋友們」第一時(shí)間閱讀,隨時(shí)有驚喜社搅。本文會(huì)在 GitHub https://github.com/JavaWorld 收錄驻债,熱騰騰的技術(shù)乳规、框架、面經(jīng)合呐、解決方案驯妄,我們都會(huì)以最美的姿勢(shì)第一時(shí)間送達(dá),歡迎 Star ~ 我們未來(lái) 不止文章合砂!想進(jìn)讀者群的伙伴歡迎撩我個(gè)人號(hào):panshenlian青扔,備注「加群」我們?nèi)豪餁g聊吧 ~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市翩伪,隨后出現(xiàn)的幾起案子微猖,更是在濱河造成了極大的恐慌,老刑警劉巖缘屹,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凛剥,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡轻姿,警方通過(guò)查閱死者的電腦和手機(jī)犁珠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)互亮,“玉大人犁享,你說(shuō)我怎么就攤上這事”荩” “怎么了炊昆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)威根。 經(jīng)常有香客問(wèn)我凤巨,道長(zhǎng),這世上最難降的妖魔是什么洛搀? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任敢茁,我火速辦了婚禮,結(jié)果婚禮上留美,老公的妹妹穿的比我還像新娘彰檬。我一直安慰自己,他們只是感情好独榴,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布僧叉。 她就那樣靜靜地躺著奕枝,像睡著了一般棺榔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上隘道,一...
    開(kāi)封第一講書(shū)人閱讀 52,394評(píng)論 1 310
  • 那天症歇,我揣著相機(jī)與錄音郎笆,去河邊找鬼。 笑死忘晤,一個(gè)胖子當(dāng)著我的面吹牛宛蚓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播设塔,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼凄吏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了闰蛔?” 一聲冷哼從身側(cè)響起痕钢,我...
    開(kāi)封第一講書(shū)人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎序六,沒(méi)想到半個(gè)月后任连,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡例诀,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年随抠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片繁涂。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拱她,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出扔罪,到底是詐尸還是另有隱情椭懊,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布步势,位于F島的核電站氧猬,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏坏瘩。R本人自食惡果不足惜盅抚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望倔矾。 院中可真熱鬧妄均,春花似錦、人聲如沸哪自。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)壤巷。三九已至邑彪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胧华,已是汗流浹背寄症。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工宙彪, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人有巧。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓释漆,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親篮迎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子男图,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

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

  • 1.異常管理的最佳做法 如果可以正確處理異常,則應(yīng)該被捕獲甜橱,否則應(yīng)該拋出異常享言。 2.為什么try中定義的變量不能用...
    03ngnntds閱讀 274評(píng)論 0 0
  • 1 受檢異常 VS 非受檢異常 簡(jiǎn)單的說(shuō),受檢異常必須在方法中被顯示的捕捉渗鬼,或者在方法的throws語(yǔ)句中被拋出览露。...
    六尺帳篷閱讀 2,578評(píng)論 0 11
  • 目錄介紹 10.0.0.1 見(jiàn)過(guò)哪些運(yùn)行時(shí)異常?異常處理機(jī)制知道哪些譬胎?從異常是否必須需要被處理的角度來(lái)看怎么分類(lèi)差牛?...
    楊充211閱讀 481評(píng)論 0 1
  • Java 提供了一種健壯且面向?qū)ο蟮姆椒▉?lái)處理稱(chēng)為 Java異常處理的異常情況。 1. Java中的異常是什么堰乔? ...
    淡定_蝸牛閱讀 607評(píng)論 0 1
  • 久違的晴天偏化,家長(zhǎng)會(huì)。 家長(zhǎng)大會(huì)開(kāi)好到教室時(shí)镐侯,離放學(xué)已經(jīng)沒(méi)多少時(shí)間了侦讨。班主任說(shuō)已經(jīng)安排了三個(gè)家長(zhǎng)分享經(jīng)驗(yàn)。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,528評(píng)論 16 22