Java 中的異常處理
? ? 在Java 中 通過(guò) Throwable 及其子類(lèi)描述各種不同的異常類(lèi)型

????Throwable 有兩個(gè)重要的子類(lèi): Exception 和 Error。
????Error:這些錯(cuò)誤是不可查的,因?yàn)樗麄冊(cè)趹?yīng)用程序的控制和處理能力之外,而且絕大多數(shù)是程序運(yùn)行時(shí)不允許出現(xiàn)的狀況;對(duì)于設(shè)計(jì)合理的程序,即使發(fā)生了錯(cuò)誤,本質(zhì)上也不應(yīng)該試圖去處理它所引起的異常狀況,因此我們編寫(xiě)程序時(shí)不需要關(guān)心這類(lèi)異常。
????Exception:是程序本身可以處理的異常,異常處理通常是針對(duì)這種類(lèi)型異常的處理;
????Exception類(lèi)包含 checked exception 和 unchecked exception;
?????????checked exception: Java 編譯器會(huì)檢查這些異常,當(dāng)程序中可能出現(xiàn)這類(lèi)異常,要求必須進(jìn)行異常處理,否則編譯不會(huì)通過(guò);
? ? ? ? unchecked exception:Java 編譯器不會(huì)檢查這些異常,在程序中可以選擇捕獲處理,也可以不處理,照樣能通過(guò)編譯。
異常處理
? ? 在 Java 中,異常處理機(jī)制為: 拋出異常、捕獲異常;
? ? 拋出異常
? ? ? ? 當(dāng)一個(gè)方法出現(xiàn)錯(cuò)誤引發(fā)異常時(shí),方法創(chuàng)建異常對(duì)象并交付運(yùn)行時(shí)系統(tǒng);
? ? ? ? 異常對(duì)象包含了異常類(lèi)型 和 異常出現(xiàn)的程序狀態(tài)等信息;
? ? ? ? 運(yùn)行時(shí)系統(tǒng)負(fù)責(zé)尋找處置異常的代碼并執(zhí)行。
? ? 捕獲異常
? ? ? ? 在方法拋出異常之后,運(yùn)行時(shí)系統(tǒng)將轉(zhuǎn)為尋找合適的異常處理器;
? ? ? ? 運(yùn)行時(shí)系統(tǒng)從發(fā)生異常的方法開(kāi)始,依次回查調(diào)用棧中的方法,當(dāng)異常處理器所能處理的異常類(lèi)型 與 方法拋出的異常類(lèi)型相符時(shí),即為合適的異常處理器;
? ? ? ? 當(dāng)運(yùn)行時(shí)系統(tǒng)遍歷調(diào)用棧而未找到合適的異常處理器,則運(yùn)行時(shí)系統(tǒng)終止,同時(shí),意味著 Java 程序的終止;
? ? ? ? 對(duì)于運(yùn)行時(shí)異常、錯(cuò)誤或可查異常,java 技術(shù)所要求的異常處理方式有所不同;
? ? ? ? 總體來(lái)說(shuō),java 規(guī)定: 對(duì)于可查異常必須捕獲、或者聲明拋出。允許忽略不可查的 RuntimeException 和 Error;
? ? ? ? 簡(jiǎn)單來(lái)說(shuō), 異??偸窍缺粧伋?,后被捕獲的。
? ??實(shí)現(xiàn): 通過(guò) try、catch、finally、throw、throws 關(guān)鍵字 來(lái)實(shí)現(xiàn)



? ? ? ? ? 終止 finally 執(zhí)行的 唯一情況

? ? throw & throws
? ? ? ? 可以通過(guò) throws 聲明將要拋出何種類(lèi)型的異常,通過(guò) throw 將產(chǎn)生的異常拋出;
? ??????throws
? ? ? ? ? ? 如果一個(gè)方法可能會(huì)出現(xiàn)異常,但是沒(méi)有能力處理這種異常,可以在方法聲明處用 throws 子句來(lái)聲明拋出異常;

? ? ? ? ? ? 當(dāng)方法拋出異常列表中的異常時(shí),方法將不對(duì)這些類(lèi)型及其子類(lèi)型的異常做處理,而?拋向?調(diào)用該方法?的?方法,由 它去處理;
? ? ? ? ? ? throws?的使用規(guī)則
????????????1、如果是不可查異常(unchecked exception),即Error、RuntimeException或它們的子類(lèi),那么可以不使用throws關(guān)鍵字來(lái)聲明要拋出的異常,編譯仍能順利通過(guò),但在運(yùn)行時(shí)會(huì)被系統(tǒng)拋出;
????????????2、如果一個(gè)方法中可能出現(xiàn)可查異常,要么用 try-catch 語(yǔ)句捕獲,要么用 throws 子句聲明將它拋出,否則會(huì)導(dǎo)致編譯錯(cuò)誤;
????????????3、當(dāng)拋出了異常,則該方法的調(diào)用者?必須處理或者重新拋出該異常;
????????????4、當(dāng)子類(lèi)重寫(xiě)父類(lèi)拋出異常的方法時(shí),聲明的異常必須是父類(lèi)方法所聲明異常的同類(lèi)或子類(lèi)。
? ??????throw?


? ? ? ? 比如 throw new IOException();
自定義異常
? ? 使用 Java 內(nèi)置的異常類(lèi)可以描述在編程時(shí)出現(xiàn)的大部分異常情況;
? ? 也可以通過(guò)自定義異常描述特定業(yè)務(wù)產(chǎn)生的異常類(lèi)型;
? ? 自定義異常,就是定義一個(gè)類(lèi),去繼承 Throwable 類(lèi)或者 它的子類(lèi)



異常鏈
? ??有時(shí)候我們會(huì)捕獲一個(gè)異常后再拋出另一個(gè)異常;
???異常鏈就是:將異常發(fā)生的原因一個(gè)傳一個(gè)串起來(lái),即把底層的異常信息傳給上層,這樣逐層拋出.
? ? 需要將 底層的異常信息 逐層的往上拋,不然 會(huì)造成丟失;
? ? new Exception("我是新產(chǎn)生的異常1", e);? // e 就是本層的 錯(cuò)誤信息
? ? 另一種形式
? ??????Exception e1=new Exception("我是新產(chǎn)生的異常2");
????????e1.initCause(e);
????????throw e1;
