在Java應用程序中,有兩種處理異常的方法:處理異常和聲明異常。
處理異常:try、catch和finally
若要捕捉異常,必須向代碼中添加異常處理程序塊。這個Java結構可以包含三個部分,
有Java關鍵詞。下面的示例使用try-catch-finally代碼結構。
1導入Java . io . *;
2公共類EchoInputTryCatchFinally {
3 public static void main(String args[]){
4 System.out.println("輸入要回顯的文本:");
5 InputStreamReader ISR = new InputStreamReader(system . in);
6 buffered reader input reader = new buffered reader(ISR);
7嘗試{
8字符串input line = input reader . readline();
9 system . out . println(" Read:"+input line);
10 }
11 catch(io exception exc){
12 System.out.println("遇到異常:"+exc);
13 }
14最後{
15 system . out . println(" End。");
16 }
17 }
18}
其中包括:
Try塊:當壹個或多個語句被放入try時,意味著這些語句可能會拋出異常。編譯器知道可能會發生異常,所以它用壹個特殊的結構計算塊中的所有語句。
Catch塊:當問題發生時,壹個選項是定義壹個代碼塊來處理問題,這就是catch塊的目的。catch塊是try塊生成的異常的接收者。基本原理是,壹旦產生異常,try塊的執行就會停止,JVM會尋找相應的JVM。
Finally塊:還可以定義壹個finally塊,無論運行try塊代碼的結果如何,這個塊中的代碼都會運行。在所有常見環境中,finally塊都將運行。無論try塊是否完全運行,無論是否生成異常,無論是否在catch塊中處理,finally塊都將被執行。
嘗試-捕捉-最終規則:
必須在try之後添加catch或finally塊。Try塊後面可以同時跟catch和finally塊,但至少有壹個塊。
必須遵循塊順序:如果您的代碼同時使用catch和finally塊,則必須將catch塊放在try塊之後。
catch塊與相應的異常類的類型相關。
壹個try塊可以有多個catch塊。如果是,則執行第壹個匹配塊。
可嵌套的嘗試-捕捉-最終結構。
在try-catch-finally結構中,可以再次引發異常。
最後總是以以下幾種情況結束:JVM過早終止(調用系統。exit(int));在finally塊中引發未處理的異常;計算機電源故障、火災或病毒攻擊。
宣布例外
若要聲明異常,必須將其添加到方法簽名塊的末尾。下面是壹個例子:
public void errorProneMethod(int input)拋出java.io.IOException {
//方法的代碼,包括壹個或多個方法
//可能產生IOException的調用
}
這樣,聲明的異常將被傳遞給方法調用方,編譯器也將被告知該方法的任何調用方必須遵守處理或聲明規則。聲明例外的規則如下:
您必須聲明該方法可能引發的任何已檢查的異常。
未檢查的異常不是必需的,可以聲明也可以不聲明。
調用方法必須遵循處理和聲明可檢測異常的任何規則。如果重寫方法,則不能聲明不同於重寫方法的異常。任何聲明的異常都必須與重寫方法聲明的異常屬於同壹類或子類。
回到頂端
Java異常處理的分類
Java異常可以分為可檢測異常、未檢測異常和自定義異常。
可檢測的異常
可檢測的異常由編譯器進行驗證,編譯器將對任何引發異常的方法強制執行處理或聲明規則,例如,sqlExecption就是壹個檢測到的異常。當您連接到JDBC時,如果您沒有捕獲到這個異常,編譯器將會失敗,並且不允許編譯。
未檢測到的異常
未檢測到的異常不遵循處理或聲明規則。當產生這樣的異常時,沒有必要采取任何適當的動作,並且編譯器不會檢查這樣的異常是否已經被解決。例如,如果數組的長度為3,當使用下標3時,將會發生數組下標越界異常。JVM不會檢測到這個異常,由程序員來判斷。有兩個主要的類定義了非檢測異常:RuntimeException和Error。
錯誤子類屬於未檢測到的異常,因為無法預測其生成時間。如果Java應用程序內存不足,則會出現OutOfMemoryError隨時可能出現;原因壹般不是應用程序的特殊調用,而是JVM本身。此外,錯誤通常表示應用程序無法解決的嚴重問題。
RuntimeException類也是壹種非檢測性異常,因為常見的JVM操作導致的運行時異常隨時都有可能發生,而這樣的異常壹般是由特定的操作導致的。但是這些操作在Java應用程序中會頻繁出現。因此,它們不受編譯器檢查和處理或聲明規則的限制。
自定義異常
自定義異常用於表示應用程序中的某些類型的錯誤,並為代碼中可能出現的壹個或多個問題提供新的含義。它可以顯示代碼的多個位置之間的錯誤的相似性,區分代碼運行時可能出現的具有相似問題的壹個或多個錯誤,或者給出應用程序中壹組錯誤的具體含義。例如,在操作隊列時,可能會出現兩種情況:當隊列為空時試圖刪除壹個元素;當隊列已滿時,試圖添加元素。您需要定制兩個異常來處理這兩種情況。
Java異常處理的原則和禁忌
Java異常處理的原則
盡可能多地處理異常。
為了盡可能多地處理異常,如果條件確實不允許在您自己的代碼中處理異常,請考慮聲明異常。避免在代碼中處理異常,而只是聲明它們,這是壹種錯誤且依賴的做法。
具體問題具體解決
exception的部分優勢在於,它可以為不同類型的問題提供不同的處理操作。有效的異常處理的關鍵是識別特定的故障場景,並開發特定的相應行為來解決該場景。為了充分利用異常處理能力,有必要為特定類型的問題構建特定的處理器塊。
記錄可能影響應用程序操作的異常。
至少采取壹些永久性的措施來記錄可能影響應用程序運行的異常。理想情況下,當然是第壹次解決導致異常的基本問題。但是,無論采用哪種治療操作,潛在的關鍵問題都應始終記錄在案。雖然這個操作很簡單,但它可以幫助您用很少的時間跟蹤應用程序中復雜問題的原因。
根據情況將異常轉換為業務上下文。
要通知應用程序特定的問題,必須將應用程序轉換為不同的形式。如果異常由特定於業務的狀態表示,代碼就更容易維護。在某種意義上,每當異常被傳遞到不同的上下文(即另壹個技術層)時,它都應該被轉換成對新上下文有意義的形式。
Java異常處理的禁忌
壹般不要忽略異常。
在異常處理塊中,最危險的操作之壹是在沒有通知的情況下處理異常。如下例所示:
1嘗試{
2 class . forname(" business . domain . customer ");
3 }
4 catch(ClassNotFoundException exc){ }
經常可以在代碼塊中看到類似的代碼塊。有些人在編碼時總喜歡簡單快速地寫出空的處理器塊,通過聲稱準備在“後期”添加恢復代碼來“安慰自己”,但這個“後期”卻變成了“無限期”。
這種做法有什麽弊端?如果這個異常對應用程序的其余部分沒有任何負面影響,那就沒問題。但事實往往並非如此,異常會擾亂應用程序的狀態。在這壹點上,這樣的代碼無異於掩耳盜鈴。
如果這有輕微的影響,應用程序可能會表現得很奇怪。例如,應用程序設置的值丟失,或者GUI無效。如果問題很嚴重,應用程序可能有重大問題,因為異常沒有記錄最初的故障點,並且很難處理,比如重復的NullPointerExceptions。
如果采取措施記錄捕獲的異常,就不可能遇到這個問題。事實上,除非確認異常對其余代碼沒有影響,否則至少要記錄下來。進壹步,千萬不要忽視問題;否則風險很大,會導致後期不可預知的後果。
不要使用覆蓋異常處理塊。
另壹個危險的過程是毛毯處理器。該代碼的基本結構如下:
1嘗試{
2 // …
3 }
4捕捉(例外e){
5 // …
6 }
使用覆蓋異常處理塊有兩個先決條件:
1.代碼中只有壹種問題。
這可能是真的,但即使如此,您也不應該使用覆蓋異常處理來捕獲更具體的異常形式。
2.單壹恢復操作始終適用。
這幾乎是絕對錯誤的。幾乎沒有壹種方法可以放之四海而皆準,可以處理任何出現的問題。
分析壹下如果妳像這樣寫代碼會發生什麽。只要方法壹直拋出預期的異常集,壹切都沒問題。但是,如果拋出了意外的異常,您將看不到要采取的操作。當覆蓋處理器對新的異常類執行相同的任務時,它只能間接地看到異常處理結果。如果代碼不打印或記錄語句,您將根本看不到結果。
更糟糕的是,當代碼改變時,覆蓋處理器將繼續作用於所有新的異常類型,並以相同的方式處理所有類型。
壹般不要把壹個具體的異常變成更壹般的異常。
把壹個特定的異常轉換成更壹般的異常是錯誤的。壹般來說,這將取消最初拋出異常時生成的上下文,當異常傳遞到系統的其他部分時,這將更加難以處理。請參見以下示例:
1嘗試{
2 //容易出錯的代碼
3 }
4 catch(IOException e){
5 String msg = "如果妳以前沒有問題,現在就有了!";
6拋出新異常(msg);
7 }
因為沒有關於原始異常的信息,所以處理器塊不能確定問題的原因,並且不知道如何糾正它。
不要處理可避免的異常。
對於壹些異常類型,實際上根本不需要處理。通常運行時異常屬於這壹類。在處理空指針或數據索引等問題時,沒有必要求助於異常處理。
Java異常處理的應用實例
在定義銀行類別時,如果取款金額大於余額,則需要破例。
定義壹個異常類,insufficientFundsException。如果余額小於提取金額,則提取方法可能會出現例外。
在處理異常時,調用撤銷時,因此,撤銷方法應該聲明拋出異常,並由上級方法調用。
異常類:
類不足FundsExceptionextends異常{
私人銀行excepbank//銀行對象
私有雙excepAmount//要提取的錢
資金不足異常(銀行賬戶,雙倍金額)
{ excepbank = ba
excepAmount = dAmount
}
公共字符串excepMessage(){
String str= "余額為"+excepbank.balance
+ "\n"+"取款是"+excepAmount;
返回字符串;
}
}//異常類
銀行類別:
銀行類別{
雙平衡;//存款數量
銀行(雙余額){ this.balance =余額;}
公共無效存款(雙倍金額){
if(da mount & gt;0.0)balance+= da mount;
}
公眾無效取款(雙倍金額)
拋出資金不足異常{
if(balance & lt;拋出新的
不足基金異常(this,da mount);
balance = balance-da mount;
}
public void showBalance(){
System.out.println("余額為"+(int)balance));
}
}
前端呼叫:
公共類ExceptionDemo{
公共靜態void main(String args[]){
嘗試{
銀行ba =新銀行(50);
ba .取款(100);
System.out.println("提現成功!");
}catch(資金不足異常e) {
system . out . println(e . tostring());
system . out . println(e . excepmessage());
}
}
}
回到頂端
摘要
在使用Java語言的軟件開發和測試腳本開發中,Java異常處理是壹個非常重要的方面。註意異常處理會使妳開發的代碼更加健壯和穩定。本文系統闡述了Java異常處理的原理和方法。可以幫助讀者更清楚地理解Java異常處理機制,在開發代碼時更靈活地使用它。