Java基礎(chǔ)再回顧-Java異常篇

什么是Java異常

異常是一個(gè)事件,它發(fā)生在程序運(yùn)行期間济蝉,干擾了正常的指令流程。Java通 過(guò)API中Throwable類的眾多子類描述各種不同的異常。因而王滤,Java異常都是對(duì)象贺嫂,是Throwable子類的實(shí)例,描述了出現(xiàn)在一段編碼中的 錯(cuò)誤條件淑仆。當(dāng)條件生成時(shí)涝婉,錯(cuò)誤將引發(fā)異常。

Java異常

Java異常結(jié)構(gòu)圖

Java異常結(jié)構(gòu)圖.png
   Throwable:Throwable 指定代碼中可用異常傳播機(jī)制通過(guò)Java 應(yīng)用程序傳輸?shù)娜魏螁?wèn)題的共性蔗怠。有兩個(gè)重要的子類:Exception(異常)和Error(錯(cuò)誤)墩弯,二者都是 Java 異常處理的重要子類,各自都包含大量子類寞射。

   Error:程序無(wú)法處理的錯(cuò)誤渔工,表示運(yùn)行程序中較嚴(yán)重問(wèn)題。大多數(shù)錯(cuò)誤與Coder無(wú)關(guān)桥温,而表示代碼運(yùn)行時(shí)JVM出現(xiàn)的問(wèn)題引矩。

   Exception:程序本身可以處理的異常。

   區(qū)別:異常能被程序本身處理侵浸,錯(cuò)誤是無(wú)法處理旺韭。

  運(yùn)行時(shí)異常:RuntimeException類及其子類異常,如NullPointerException掏觉、IndexOutBoundsException等区端,這些異常是不檢查異常,可以選擇捕獲處理澳腹,也可以不捕獲织盼。

  運(yùn)行時(shí)異常的特點(diǎn)是Java編譯器不會(huì)檢查它,也就是說(shuō)酱塔,當(dāng)程序中可能出現(xiàn)這類異常沥邻,即使沒(méi)有用try-catch語(yǔ)句捕獲它,也沒(méi)有用throws子句聲明拋出它羊娃,也會(huì)編譯通過(guò)唐全。

  非運(yùn)行時(shí)異常:是RuntimeException以外的異常,類型上都屬于Exception類及其子類蕊玷。從程序語(yǔ)法角度講是必須進(jìn)行處理的異常芦瘾,如果不處理,程序就不能編譯通過(guò)集畅。如IOException、SQLException等以及用戶自定義的Exception異常缅糟,一般情況下不自定義檢查異常挺智。

處理異常機(jī)制

拋出異常:當(dāng)一個(gè)方法出現(xiàn)錯(cuò)誤引發(fā)異常時(shí),方法創(chuàng)建異常對(duì)象并交付運(yùn)行時(shí)系統(tǒng),異常對(duì)象中包含了異常類型和異常出現(xiàn)時(shí)的程序狀態(tài)等異常信息赦颇。運(yùn)行時(shí)系統(tǒng)負(fù)責(zé)尋找處置異常的代碼并執(zhí)行二鳄。

捕獲異常:在方法拋出異常之后,運(yùn)行時(shí)系統(tǒng)將轉(zhuǎn)為尋找合適的異常處理器(exception handler)媒怯。潛在的異常處理器是異常發(fā)生時(shí)依次存留在調(diào)用棧中的方法的集合订讼。當(dāng)異常處理器所能處理的異常類型與方法拋出的異常類型相符時(shí),即為合適的異常處理器扇苞。運(yùn)行時(shí)系統(tǒng)從發(fā)生異常的方法開(kāi)始欺殿,依次回查調(diào)用棧中的方法,直至找到含有合適異常處理器的方法并執(zhí)行鳖敷。當(dāng)運(yùn)行時(shí)系統(tǒng)遍歷調(diào)用棧而未找到合適的異常處理器脖苏,則運(yùn)行時(shí)系統(tǒng)終止。同時(shí)定踱,意味著Java程序的終止棍潘。

總體來(lái)說(shuō):Java規(guī)定,對(duì)于可查異常必須捕獲崖媚、或者聲明拋出亦歉。允許忽略不可查的RuntimeException和Error。

捕獲異常

1畅哑、try-catch語(yǔ)句

    關(guān)鍵詞try后的一對(duì)大括號(hào)將一塊可能發(fā)生異常的代碼包起來(lái)肴楷,稱為監(jiān)控區(qū)域。Java方法在運(yùn)行過(guò)程中出現(xiàn)異常敢课,則創(chuàng)建異常對(duì)象阶祭。將異常拋出監(jiān)控區(qū)域之外,由Java運(yùn)行時(shí)系統(tǒng)試圖尋找匹配的catch子句以捕獲異常直秆。若有匹配的catch子句濒募,則運(yùn)行其異常處理代碼,try-catch語(yǔ)句結(jié)束圾结。
    匹配的原則是:如果拋出的異常對(duì)象屬于catch子句的異常類瑰剃,或者屬于該異常類的子類,則認(rèn)為生成的異常對(duì)象與catch塊捕獲的異常類型相匹配筝野。
    需要注意的是晌姚,一旦某個(gè)catch捕獲到匹配的異常類型,將進(jìn)入異常處理代碼歇竟,就意味著整個(gè)try-catch語(yǔ)句結(jié)束挥唠。其他的catch子句不再有匹配和捕獲異常類型的機(jī)會(huì)。

2焕议、try-catch-finally語(yǔ)句

  finally子句表示無(wú)論是否出現(xiàn)異常宝磨,都應(yīng)當(dāng)執(zhí)行的內(nèi)容。
階段小結(jié)
  **try ****塊:**用于捕獲異常。其后可接零個(gè)或多個(gè)catch塊唤锉,如果沒(méi)有      catch塊世囊,則必須跟一個(gè)finally塊。
  **catch ****塊:**用于處理try捕獲到的異常窿祥。
  **finally ****塊:**無(wú)論是否捕獲或處理異常株憾,finally塊里的語(yǔ)句都會(huì)被執(zhí)行。當(dāng)在try塊或catch塊中遇到return語(yǔ)句時(shí)晒衩,finally語(yǔ)句塊將在方法返回之前被執(zhí)行嗤瞎。在以下4種特殊情況下,finally塊不會(huì)被執(zhí)行:
                    1)在finally語(yǔ)句塊中發(fā)生了異常浸遗。
                    2)在前面的代碼中用了System.exit()退出程序猫胁。
                    3)程序所在的線程死亡。
                    4)關(guān)閉CPU跛锌。

3. try-catch-finally 規(guī)則(異常處理語(yǔ)句的語(yǔ)法規(guī)則):

  1)  必須在 try 之后添加 catch 或 finally 塊弃秆。try 塊后可同時(shí)接 catch 和 finally 塊,但至少有一個(gè)塊髓帽。
  2) 必須遵循塊順序:若代碼同時(shí)使用 catch 和 finally 塊菠赚,則必須將 catch 塊放在 try 塊之后。
  3) catch 塊與相應(yīng)的異常類的類型相關(guān)郑藏。
  4) 一個(gè) try 塊可能有多個(gè) catch 塊衡查。若如此,則執(zhí)行第一個(gè)匹配塊必盖。即Java虛擬機(jī)會(huì)把實(shí)際拋出的異常對(duì)象依次和各個(gè)catch代碼塊聲明的異常類型匹配拌牲,如果異常對(duì)象為某個(gè)異常類型或其子類的實(shí)例,就執(zhí)行這個(gè)catch代碼塊歌粥,不會(huì)再執(zhí)行其他的 catch代碼塊
  5) 可嵌套 try-catch-finally 結(jié)構(gòu)塌忽。
  6) 在 try-catch-finally 結(jié)構(gòu)中,可重新拋出異常失驶。
  7) 除了下列情況土居,總將執(zhí)行 finally 做為結(jié)束:
       JVM 過(guò)早終止(調(diào)用 System.exit(int));
       在 finally 塊中拋出一個(gè)未處理的異常嬉探;
       計(jì)算機(jī)斷電擦耀、失火、或遭遇病毒攻擊涩堤。

4. try眷蜓、catch、finally語(yǔ)句塊的執(zhí)行順序:

    1)當(dāng)try沒(méi)有捕獲到異常時(shí):try語(yǔ)句塊中的語(yǔ)句逐一被執(zhí)行胎围,程序?qū)⑻^(guò)catch語(yǔ)句塊吁系,執(zhí)行finally語(yǔ)句塊和其后的語(yǔ)句芹敌;

    2)當(dāng)try捕獲到異常,catch語(yǔ)句塊里沒(méi)有處理此異常的情況:當(dāng)try語(yǔ)句塊里的某條語(yǔ)句出現(xiàn)異常時(shí)垮抗,而沒(méi)有處理此異常的catch語(yǔ)句塊時(shí),此異常將會(huì)拋給JVM處理碧聪,finally語(yǔ)句塊里的語(yǔ)句還是會(huì)被執(zhí)行冒版,但finally語(yǔ)句塊后的語(yǔ)句不會(huì)被執(zhí)行;

    3)當(dāng)try捕獲到異常逞姿,catch語(yǔ)句塊里有處理此異常的情況:在try語(yǔ)句塊中是按照順序來(lái)執(zhí)行的辞嗡,當(dāng)執(zhí)行到某一條語(yǔ)句出現(xiàn)異常時(shí),程序?qū)⑻絚atch語(yǔ)句塊滞造,并與catch語(yǔ)句塊逐一匹配续室,找到與之對(duì)應(yīng)的處理程序,其他的catch語(yǔ)句塊將不會(huì)被執(zhí)行谒养,而try語(yǔ)句塊中挺狰,出現(xiàn)異常之后的語(yǔ)句也不會(huì)被執(zhí)行,catch語(yǔ)句塊執(zhí)行完后买窟,執(zhí)行finally語(yǔ)句塊里的語(yǔ)句丰泊,最后執(zhí)行finally語(yǔ)句塊后的語(yǔ)句;

拋出異常

1. throws拋出異常

  如果一個(gè)方法可能會(huì)出現(xiàn)異常始绍,但沒(méi)有能力處理這種異常瞳购,可以在方法聲明處用throws子句來(lái)聲明拋出異常。   
 **Throws拋出異常的規(guī)則:**
  1) 如果是不可查異常(unchecked exception)亏推,即Error学赛、RuntimeException或它們的子類,那么可以不使用throws關(guān)鍵字來(lái)聲明要拋出的異常吞杭,編譯仍能順利通過(guò)盏浇,但在運(yùn)行時(shí)會(huì)被系統(tǒng)拋出。
  2)必須聲明方法可拋出的任何可查異常(checked exception)篇亭。即如果一個(gè)方法可能出現(xiàn)受可查異常缠捌,要么用try-catch語(yǔ)句捕獲,要么用throws子句聲明將它拋出译蒂,否則會(huì)導(dǎo)致編譯錯(cuò)誤
  3)僅當(dāng)拋出了異常曼月,該方法的調(diào)用者才必須處理或者重新拋出該異常。當(dāng)方法的調(diào)用者無(wú)力處理該異常的時(shí)候柔昼,應(yīng)該繼續(xù)拋出哑芹,而不是囫圇吞棗。
  4)調(diào)用方法必須遵循任何可查異常的處理和聲明規(guī)則捕透。若覆蓋一個(gè)方法聪姿,則不能聲明與覆蓋方法不同的異常碴萧。聲明的任何異常必須是被覆蓋方法所聲明異常的同類或子類。

2. throw拋出異常

  throw總是出現(xiàn)在函數(shù)體中末购,用來(lái)拋出一個(gè)Throwable類型的異常破喻。程序會(huì)在throw語(yǔ)句后立即終止,它后面的語(yǔ)句執(zhí)行不到盟榴,然后在包含它的所有try塊中(可能在上層調(diào)用函數(shù)中)從里向外尋找含有與其匹配的catch子句的try塊曹质。

Throwable類中的常用方法:

getCause():返回拋出異常的原因。如果cause不存在或未知擎场,則返回null

getMessage():返回異常的消息信息

printStackTrace():對(duì)象的堆棧跟蹤輸出至錯(cuò)誤輸出流羽德,作為字段System.err的值

Java常見(jiàn)異常

在Java中提供了一些異常用來(lái)描述經(jīng)常發(fā)生的錯(cuò)誤,對(duì)于這些異常迅办,有的需要程序員進(jìn)行捕獲處理或聲明拋出宅静,有的是由Java虛擬機(jī)自動(dòng)進(jìn)行捕獲處理。Java中常見(jiàn)的異常類:

1. runtimeException子類:

1站欺、 java.lang.ArrayIndexOutOfBoundsException    數(shù)組索引越界異常姨夹。當(dāng) 對(duì)數(shù)組的索引值為負(fù)數(shù)或大于等于數(shù)組大小時(shí)拋出。   
2镊绪、java.lang.ArithmeticException    算術(shù)條件異常匀伏。譬如:整數(shù)除零等。    
3蝴韭、java.lang.NullPointerException    空指針異常够颠。當(dāng)應(yīng)用試圖在要求使用對(duì)象的地方使用了null時(shí),拋出該異常榄鉴。譬如:調(diào)用null對(duì)象的實(shí)例方法履磨、訪問(wèn)null對(duì)象的屬性、計(jì)算null對(duì)象的長(zhǎng)度庆尘、使用throw語(yǔ)句拋出null等等    
4剃诅、java.lang.ClassNotFoundException    找不到類異常。當(dāng)應(yīng)用試圖根據(jù)字符串形式的類名構(gòu)造類驶忌,而在遍歷CLASSPAH之后找不到對(duì)應(yīng)名稱的class文件時(shí)矛辕,拋出該異常。   
5付魔、java.lang.NegativeArraySizeException  數(shù)組長(zhǎng)度為負(fù)異常
6聊品、java.lang.ArrayStoreException 數(shù)組中包含不兼容的值拋出的異常
7、java.lang.SecurityException 安全性異常
8几苍、java.lang.IllegalArgumentException 非法參數(shù)異常

2.IOException

  IOException:操作輸入流和輸出流時(shí)可能出現(xiàn)的異常翻屈。
  EOFException   文件已結(jié)束異常
  FileNotFoundException   文件未找到異常

3.** 其他**

  ClassCastException    類型轉(zhuǎn)換異常類
  ArrayStoreException  數(shù)組中包含不兼容的值拋出的異常
  SQLException   操作數(shù)據(jù)庫(kù)異常類  
  NoSuchFieldException   字段未找到異常
  NoSuchMethodException   方法未找到拋出的異常
  NumberFormatException    字符串轉(zhuǎn)換為數(shù)字拋出的異常
  StringIndexOutOfBoundsException 字符串索引超出范圍拋出的異常
  IllegalAccessException  不允許訪問(wèn)某類異常
  InstantiationException  當(dāng)應(yīng)用程序試圖使用Class類中的newInstance()方法創(chuàng)建一個(gè)類的實(shí)例,而指定的類對(duì)象無(wú)法被實(shí)例化時(shí)妻坝,拋出該異常

?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末伸眶,一起剝皮案震驚了整個(gè)濱河市惊窖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌厘贼,老刑警劉巖界酒,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異嘴秸,居然都是意外死亡盾计,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門赁遗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人族铆,你說(shuō)我怎么就攤上這事岩四。” “怎么了哥攘?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵剖煌,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我逝淹,道長(zhǎng)耕姊,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任栅葡,我火速辦了婚禮茉兰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘欣簇。我一直安慰自己规脸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布熊咽。 她就那樣靜靜地躺著莫鸭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪横殴。 梳的紋絲不亂的頭發(fā)上被因,一...
    開(kāi)封第一講書(shū)人閱讀 49,111評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音衫仑,去河邊找鬼梨与。 笑死,一個(gè)胖子當(dāng)著我的面吹牛惑畴,可吹牛的內(nèi)容都是我干的蛋欣。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼如贷,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼陷虎!你這毒婦竟也來(lái)了到踏?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤尚猿,失蹤者是張志新(化名)和其女友劉穎窝稿,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體凿掂,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡伴榔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了庄萎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片踪少。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖糠涛,靈堂內(nèi)的尸體忽然破棺而出援奢,到底是詐尸還是另有隱情,我是刑警寧澤忍捡,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布集漾,位于F島的核電站,受9級(jí)特大地震影響砸脊,放射性物質(zhì)發(fā)生泄漏具篇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一凌埂、第九天 我趴在偏房一處隱蔽的房頂上張望驱显。 院中可真熱鬧,春花似錦瞳抓、人聲如沸秒紧。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)熔恢。三九已至,卻和暖如春臭笆,著一層夾襖步出監(jiān)牢的瞬間叙淌,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工愁铺, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鹰霍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓茵乱,卻偏偏與公主長(zhǎng)得像茂洒,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瓶竭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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