大家好,我是IT修真院鄭州分院第6期的學員李亞衡,一枚正直純潔善良的JAVA程序員
今天給大家分享一下,修真院官網JAVA任務一,深度思考中的知識點——JAVA中的異常處理機制
1.背景介紹
可能每一只程序猿都有這樣一個夢想
程序永遠不會出現問題,用戶輸入的數據永遠是正確的,邏輯一定沒有任何問題 ,選擇打開的資源也一定是存在的,連接永遠是OK的,內存永遠是夠用的……
簡單來說就是:0 error(s), 0 warning(s)
但是,不存在的...
一場總是不期而至,所以我們要處理異常
異常處理機制:天有不測風云,人有旦夕禍福,Java的程序代碼也如此,JAVA遠在設計之初就考慮到了這個問題,于是就設計了JAVA的異常處理機制。而發展至今的異常處理機制現在也已經非常的完善。
2.知識剖析
什么是異常處理?
如果某個方法不能按照正常的途徑完成任務,
就可以通過另一種路徑退出方法。
在這種情況下會拋出一個封裝了錯誤信息的對象。
此時,這個方法會立刻退出同時不返回任何值。
另外,調用這個方法的其他代碼也無法繼續執行,
異常處理機制會將代碼執行交給異常處理器。
異常的分類
java中的異常機制包括Error和Exception兩個部分。他們都繼承自一個共同的基類Throwable
Error屬于JVM運行中發生的一些錯誤,雖然并不屬于開發人員的范疇,但是有些Error還是由代碼引起的,比如StackOverflowError經常由遞歸操作引起
Exception分為兩種,檢查類型(checked)和未檢查類型(unchecked)。檢查類型的異常就是說要程序員明確的去聲明或者用try..catch語句來處理的異常,而非檢查類型的異常則沒有這些限制
下面看一張樹狀圖
換一種說法
對于嚴重的,java通過Error類來描述
對于Error一般不編寫針對性的代碼對其進行處理
對于非嚴重的,java通過Exception類來描述
對于Exception可以使用針對性的處理方式進行處理
Java異常處理涉及到五個關鍵字
分別是:try、catch、finally、throw與throws,每個關鍵字不能被單獨使用
1.try:它里面放置可能引發異常的代碼
2.catch:后面對應異常類型和一個代碼塊,用于表明該catch塊用于處理這種類型的代碼塊,可以有多個catch塊。
3.finally:主要用于回收在try塊里打開的物力資源(如數據庫連接、網絡連接和磁盤文件),異常機制總是保證finally塊總是被執行。
4.throw:用于拋出一個實際的異常,可以單獨作為語句使用,拋出一個具體的異常對象。
5.throws:用在方法簽名中,用于聲明該方法可能拋出的異常。
3.常見問題
注意點1:只有try塊是必須的,也就是說如果沒有try塊,則不可能有后面的catch塊和finally塊;
注意點2:catch塊和finally塊都是可選的,但catch塊和finally塊至少出現其中之一,也可以同時出現;
注意點3:可以有多個catch塊,捕獲父類異常的catch塊必須位于捕獲子類異常的后面;
注意點4:不能只有try塊,既沒有catch塊,也沒有finally塊;
注意點5:多個catch塊必須位于try塊之后,finally塊必須位于所有catch塊之后。
一般情況下,不要再finally塊中使用renturn或throw等導致方法終止的語句,因為一旦使用,將會導致try塊、catch塊中的return、throw語句失效。
4.解決方案
在try塊中使用退出虛擬機的語句,不過這會導致整個程序終止,最好還是不要在finally中寫return和throw語句
5.編碼實戰
public classTest1 {
public static voidmain(String[] args) {
inta =6;
intb =0;
try{// try監控區域
if(b ==0)throw newArithmeticException();//通過throw語句拋出異常
System.out.println("a/b的值是:"+ a / b);
}
catch(ArithmeticException e) {// catch捕捉異常
System.out.println("程序出現異常,變量b不能為0。");
}
System.out.println("程序正常結束。");
}
}
這個代碼主要是使用了Throw語句
public classTest1 {
public static voidmain(String[] args) {
int[] intArray =new int[3];
try{
for(inti =0;i <= intArray.length;i++) {
intArray[i] = i;
System.out.println("intArray["+ i +"] = "+ intArray[i]);
System.out.println("intArray["+ i +"]模"+ (i -2) +"的值:? "
+ intArray[i] % (i -2));
}
}catch(ArrayIndexOutOfBoundsException e) {
System.out.println("intArray數組下標越界異常。");
}catch(ArithmeticException e) {
System.out.println("除數為0異常。");
}
System.out.println("程序正常結束。");
}
}
兩個catch語句塊,主要是為了體會當異常匹配到一個catch后,講跳出方法,處理異常,其他的catch塊不會再有匹配的機會
public classTest2 {
public static voidmain(String args[]) {
inti =0;
String greetings[] = {" Hello world !"," Hello World !! ",
" HELLO WORLD !!!"};
while(i <4) {
try{
//特別注意循環控制變量i的設計,避免造成無限循環
System.out.println(greetings[i++]);
}catch(ArrayIndexOutOfBoundsException e) {
System.out.println("數組下標越界異常");
}finally{
System.out.println("--------------------------");
}
}
}
}
體會finall總會被執行
test1. 需要注意的是,一旦某個catch捕獲到匹配的異常類型,將進入異常處理代碼。一經處理結束,就意味著整個try-catch語句結束。其他的catch子句不再有匹配和捕獲異常類型的機會。
test2.
1)當try沒有捕獲到異常時:try語句塊中的語句逐一被執行,程序將跳過catch語句塊,執行finally語句塊和其后的語句;
2)當try捕獲到異常,catch語句塊里沒有處理此異常的情況:當try語句塊里的某條語句出現異常時,而沒有處理此異常的catch語句塊時,此異常將會拋
給JVM處理,finally語句塊里的語句還是會被執行,但finally語句塊后的語句不會被執行;
3)當try捕獲到異常,catch語句塊里有處理此異常的情況:在try語句塊中是按照順序來執行的,當執行到某一條語句出現異常時,程序將跳到catch語句塊,并與catch語句塊逐一匹配,找到與之對應的處理程序,其他的catch語句塊將不會被執行,而try語句塊中,出現異常之后的語句也不會被執行,catch語句塊執行完后,執行finally語句塊里的語句,最后執行finally語句塊后的語句
6.擴展思考
錯誤處理代碼和業務實現代碼混雜嚴重影響程序的可讀性,會增加程序維護的難度。在代碼健壯性和代碼可讀性上如何抉擇?
針對應用場景選擇是否需要使代碼更加健壯,程序更加穩定,如果需要,就使用異常處理機制,否則就放棄使用
7.參考文獻
http://www.cnblogs.com/maosonglin/p/6096442.html
http://blog.csdn.net/hguisu/article/details/6155636/
http://www.cnblogs.com/Bob-FD/archive/2012/09/23/2699174.html
8.更多討論
無法窮舉所有異常情況,因為人類的知識是有限的,異常情況總比可以考慮到的情況多,總有漏網之魚,怎么辦?
可以自己寫出一個異常類進行封裝使用,詳情請百度搜索:www.baidu.com ? 關鍵字:異常類編寫
PPT:https://ptteng.github.io/PPT/PPT-java/java-%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86%E6%9C%BA%E5%88%B6.html#/
感謝大家觀看!
今天的分享就到這里啦,歡迎大家點贊、轉發、留言、拍磚~