什么是異常:
1.異常字面翻譯就是“意外、例外”的意思凡壤,也就是非正常情況极阅。
2.異常本質(zhì)上是程序上的錯誤。
程序中的異常:
1 .在編譯期間出現(xiàn)的錯誤有編譯器幫助我們一起修正疗涉,然而運(yùn)行期間的錯誤便不是編譯器力所能及了,并且運(yùn)行期間的錯誤往往是難以預(yù)料的吟秩。
2. 在程序運(yùn)行過程中咱扣,意外發(fā)生的情況,背離我們程序本身的意圖的表現(xiàn)涵防,都可以理解為異常闹伪。
3. 當(dāng)程序在運(yùn)行期間出現(xiàn)了異常,如果置之不理壮池,程序可能會不正常運(yùn)行偏瓤、強(qiáng)制中斷運(yùn)行、造成用戶數(shù)據(jù)丟失椰憋、資源無法正常釋放厅克、直接導(dǎo)致系統(tǒng)崩潰。
4. Java提供了異常機(jī)制來進(jìn)行處理橙依,通過異常機(jī)制证舟,我們可以更好地提升程序的健壯性。
異常例子:
使用空的對象引用調(diào)用方法
String str =
null窗骑;System.out.println( str.length() );
數(shù)組訪問時下標(biāo)越界
int[] ary={1,2,3};
for(int i=0;
i<=3;i++){? ? System.out.println(ary[i]);? }
算術(shù)運(yùn)算時除數(shù)為0
int one= 12; int
two=0;System.out.println(one/two);
類型轉(zhuǎn)換時無法正常轉(zhuǎn)型
class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}
public class Test{
????public static void main[String[] args]{
? ? ? ? Animal a1= new Dog();
? ?????? Animal a2= new Cat();
? ? ? ? Dog d1 = (Dog)a1;
? ? ? ? Dog d2 =
(Dog)a2;????}
}
異常的分類:
Error:
? ? 1.我們編寫程序時不需要關(guān)心這類異常女责。
? ? 2.Error是程序無法處理的錯誤,大多數(shù)錯誤與代碼編寫者執(zhí)行的操作無關(guān)创译,表示是代碼運(yùn)行時JVM(Java 虛擬機(jī))出現(xiàn)的問題抵知。
? ?3.這些錯誤是不可查的,因為它們在應(yīng)用程序的控制和處理能力之外软族,而且絕大多數(shù)是程序運(yùn)行時不允許出現(xiàn)的狀況刷喜。
? ?4.對于設(shè)計合理的應(yīng)用程序來說,即使確實發(fā)生了錯誤互订,本質(zhì)上也不應(yīng)該試圖去處理它所引起的異常狀況吱肌。
Exception:
? ? 1. Exception是程序本身可以處理的異常。異常處理經(jīng)常指針對這種異常的處理.
? ? 2. Exception類的異常包括 checked exception 和 uncheckedexception仰禽。
? ?unchecked exception
? ? ? ? 1. 編譯器不要求強(qiáng)制處置的異常氮墨。
? ? ? ? 2. 包含RuntimeException類及其子類異常纺蛆。
? ? ? ? 3.? 如NullPointerException(空指針異常)、IndexOutOfBoundsException(下標(biāo)越界異常)等规揪,這些異常是unchecked exception 桥氏。
? ? ? ? 4.??Java編譯器不會檢查這些異常,在程序中可以選擇捕獲處理猛铅,也可以不處理字支,照樣正常編譯通過。
? ?checked exception
? ? ? ? 1. 編譯器要求必須處置的異常奸忽。
? ? ? ? 2.?是RuntimeException及其子類以外堕伪,其他的Exception類的子類。如IOException栗菜、SQLException等
? ? ? ? 3.?Java編譯器會檢查這些異常欠雌,當(dāng)程序中可能出現(xiàn)這類異常時,要求必須進(jìn)行異常處理疙筹,否則編譯不會通過富俄。
異常處理:?拋出異常、捕捉異常
? ??異扯兀總是先被拋出霍比,后被捕捉的。
????對于可查異常必須捕捉暴备、或者聲明拋出悠瞬。
? ??允許忽略:不可查的RuntimeException和Error。
拋出異常
? ? 1.當(dāng)一個方法出現(xiàn)錯誤引發(fā)異常時馍驯,方法創(chuàng)建異常對象并交付運(yùn)行時系統(tǒng)阁危。
? ? 2.異常對象中包括異常類型和異常出現(xiàn)的時程序狀態(tài)等異常信息。
? ? 3.運(yùn)行時系統(tǒng)負(fù)責(zé)尋找處置異常的代碼并執(zhí)行汰瘫。
捕獲異常
? ? 1. 在方法拋出異常之后狂打,運(yùn)行時系統(tǒng)將轉(zhuǎn)為尋找合適的異常處理器。
? ? 2. 運(yùn)行時系統(tǒng)從發(fā)生異常的方法開始混弥,依次回查調(diào)用棧中的方法趴乡,當(dāng)異常處理器所能處理的異常類型與方法拋出異常類型相符時,即合適的異常處理器蝗拿。
? ? 3.?當(dāng)運(yùn)行時系統(tǒng)遍歷調(diào)用棧而未找到合適的異常處理器晾捏,則運(yùn)行時系統(tǒng)終止。同時哀托,意味著Java程序的終止惦辛。
處理實現(xiàn)
通過5個關(guān)鍵字來實現(xiàn):try、catch仓手、 finally胖齐、throw玻淑、throws
捕獲:try,catch呀伙、 finally
? ? ? ? ? ?try:執(zhí)行可能執(zhí)行異常的代碼
? ? ? ? ? ?catch:捕獲異常
? ? ? ? ? ? finally:無論是否發(fā)生異常补履,代碼總能執(zhí)行
聲明:throws
? ? ? ? ? ? throws:聲明可能要拋出的異常
拋出:throw
????????????throw :手動拋出異常
?try-catch-finally
? ??
try-catch( 有異常,能處理)
? ??
try-catch(?有異常剿另,不能處理)
try-catch( 無異常)
多重catch塊
????????1. 一旦某個catch捕獲到匹配的異常類型箫锤,將進(jìn)入異常處理代碼。一經(jīng)處理結(jié)束雨女,就意味著整個try-catch語句結(jié)束谚攒。其他的catch子句不再有匹配和捕獲異常類型的機(jī)會。
????????2.?對于有多個catch子句的異常程序而言戚篙,應(yīng)該盡量將捕獲底層異常類的catch子句放在前面五鲫,同時盡量將捕獲相對高層的異常類的catch子句放在后面。否則岔擂,捕獲底層異常類的catch子句將可能會被屏蔽。
規(guī)則:
? ??????1.排列catch 語句的順序:先子類后父類浪耘。
? ??????2.發(fā)生異常時按順序逐個匹配乱灵。
????? ??3.只執(zhí)行第一個與異常類型匹配的catch語句。
try-catch-finally
1.?try塊后可以接零個或多個catch塊
2.?如果沒有catch七冲,則必須跟一個finally塊
語法組合:
try-catch
try-finally
try-catch-finally
try-catch-catch-finally
實際應(yīng)用中的經(jīng)驗與總結(jié)
????1. 處理運(yùn)行時異常時痛倚,采用邏輯去合理規(guī)避同時輔助try-catch處理。
????2.?在多重catch塊后面澜躺,可以加一個catch(Exception)來處理可能會被遺漏的異常蝉稳。
????3.?對于不確定的代碼,也可以加上try-catch掘鄙,處理潛在的異常耘戚。
????4.?盡量去處理異常,切忌只是簡單的調(diào)用printStackTrace()去打印輸出操漠。
????5.?具體如何處理異常收津,要根據(jù)不同的業(yè)務(wù)需求和異常類型去決定。
????6. 盡量添加finally語句塊去釋放占用的資源浊伙。
常見異常類型
throw & throws
? ??可以通過throws聲明將要拋出何種類型的異常撞秋,通過throw將產(chǎn)生的異常拋出。
throws:
? ??如果一個方法可能會出現(xiàn)異常嚣鄙,但沒有能力處理這種異常吻贿,可以在方法聲明處用throws子句來聲明拋出異常。方法將不對這些類型及其子類類型的異常作處理哑子,而拋向調(diào)用該方法的方法舅列,由他去處理肌割。
? ?? 汽車在運(yùn)行時可能會出現(xiàn)故障,汽車本身沒辦法處理這個故障剧蹂, 那就讓開車的人來處理 声功。
????throws語句用在方法定義時聲明該方法要拋出的異常類型。
public void method() throws Exception1,Exception2,...,ExceptionN {
// 可能產(chǎn)生異常的代碼
}
使用規(guī)則:
? ????1. 如果是不可查異常(unchecked exception)宠叼,即Error先巴、RuntimeException或它們的子類,那么可以不使用throws關(guān)鍵字來聲明要拋出的異常冒冬,編譯仍能順利通過伸蚯,但在運(yùn)行時會被系統(tǒng)拋出。
????????2. 如果一個方法中可能出現(xiàn)可查異常简烤,要么用try-catch語句捕獲剂邮, 要么用throws子句聲明將它拋出,否則會導(dǎo)致編譯錯誤
????????3. 當(dāng)拋出了異常横侦,則該方法的調(diào)用者必須處理或者重新拋出該異常挥萌。
? ??????4. 當(dāng)子類重寫父類拋出異常的方法時,聲明的異常必須是父類方法所聲明異常的同類或子類枉侧。
throw:
? ??throw用來拋出一個異常引瀑。
? ? throw new IOException();?
????throw 拋出的只能夠是可拋出類Throwable 或者其子類的實例對象。
throw new String(“出錯啦”);?? 是錯誤的
自定義異常
1.使用Java內(nèi)置的異常類可以描述在編程時出現(xiàn)的大部分異常情況榨馁。
2.也可以通過自定義異常描述特定業(yè)務(wù)產(chǎn)生的異常類型憨栽。
3.所謂自定義異常,就是定義一個類翼虫,去繼承Throwable類或者? 它的子類屑柔。
異常鏈
1.有時候我們會捕獲一個異常后再拋出另一個異常。
2.顧名思義就是:將異常發(fā)生的原因一個傳一個串起來珍剑,即把底層
的異常信息傳給上層掸宛,這樣逐層拋出。
先進(jìn)后出