標籤:異常 異常處理
——Java培訓、Android培訓、iOS培訓、.Net培訓 期待與您共同交流!——
異常處理
1. 異常處理概述1.1. 使用傳回值狀態標識異常
在JAVA語言出現以前,傳統的異常處理方式多採用傳回值來標識程式出現的異常情況,這種方式雖然為程式員所熟悉,但卻有多個壞處。
首先,一個API可以返回任意的傳回值,而這些傳回值本身並不能解釋該傳回值是否代表一個異常情況發生了和該異常的具體情況,需要調用API的程式自己判斷並解釋傳回值的含義。
其次,並沒有一種機制來保證異常情況一定會得到處理,調用程式可以簡單的忽略該傳回值,需要調用API的程式員記住去檢測傳回值並處理異常情況。這種方式還讓程式碼變得冗長,尤其是當進行IO操作等容易出現異常情況的處理時,代碼的很大部分用於處理異常情況的switch分支,程式碼的可讀性變得很差。
1.2. 異常處理機制
當程式中拋出一個異常後,程式從程式中導致異常的代碼處跳出,java虛擬機器檢測尋找和try關鍵字匹配的處理該異常的catch塊,如果找到,將控制權交到catch塊中的代碼,然後繼續往下執行程式,try塊中發生異常的代碼不會被重新執行。如果沒有找到處理該異常的catch塊,在所有的finally塊代碼被執行和當前線程的所屬的ThreadGroup的uncaughtException方法被調用後,遇到異常的當前線程被中止。
2. 異常的處理和捕獲2.1. Throwable,Error和Exception
Java異常結構中定義有Throwable類,Exceotion和Error是其派生的兩個子類。其中Exception表示由於網路故障、檔案損壞、裝置錯誤、使用者輸入非法等情況導致的異常,這類異常是可以通過Java異常捕獲機制處理的。而Error表示Java運行時環境出現的錯誤,例如:JVM記憶體溢出等。
2.2. try-catch
try {…} 語句指定了一段代碼,該段代碼就是一次捕獲並處理例外的範圍。在執行過程中,該段代碼可能會產生並拋出一種或幾種類型的異常對象,它後面的catch語句分別對這些異常做相應的處理。
如果沒有列外產生,所有的catch程式碼片段都被略過不執行
在catch語句塊中是對異常進行處理的代碼。catch中聲明的異常對( catch(SomeException e) )封裝了例外狀況事件發生的資訊,在catch語句塊中可以使用這個對象的一些方法擷取這些資訊
常見格式:
...try{//可能出現異常的程式碼片段}catch(Exception e){//處理該異常的程式碼片段}...
2.3. 多個catch
每個try語句塊可以伴隨一個或多個catch語句,用於處理可能產生的不同類型的異常 。catch捕獲的異常類型由上至下的捕獲異常類型的順序應是子類到父類的
例如
try{ …}catch(NullPointerException e){//子類異常應在上面捕獲 …}catch(RuntimeException e){//父類異常在下面捕獲 … }catch(Exception e){//應養成最終捕獲Exception的習慣 …}
通常在書寫代碼的時候,我們應當在最後一個catch中捕獲Exception,這樣可以保證代碼不會因為出現一個未在catch中聲明的異常而導致捕獲失敗使得程式終止。
2.4. finally的作用
finally語句為異常處理提供一個統一的出口,使得在控制流程程轉到程式其它部分以前,能夠對程式的狀態作統一管理。
無論try所指定的程式塊中是否拋出例外,finally所指定的代碼都要被執行,通常在finally語句中可以進行資源的消除工作,如關閉開啟的檔案、刪除臨時檔案等。
finally語句塊只能定義在try語句塊之後,或者最後一個catch語句塊之後,且只能定義一次。
2.5. throw關鍵字
當程式發生錯誤而無法處理的時候,會拋出對應的異常對象,除此之外,在某些時刻,您可能會想要自行拋出異常,例如在異常處理結束後,再將異常拋出,讓下一層異常處理區塊來捕捉,若想要自行拋出異常,您可以使用“throw”關鍵詞,並產生指定的異常對象。
例如:
thrownewArithmeticException();
2.6. throws關鍵字
程式中會聲明許多方法(Method),這些方法中可能會因某些錯誤而引發異常,但您不希望直接在這個方法中處理這些異常,而希望調用這個它的方法來統一處理,這時候您可以使用“throws”關鍵詞來聲明這個方法將會拋出異常
例如:
publicstatic void stringToDate(String str)throws ParseException{ ……}
2.7. 重寫方法時的throws
當使用繼承時,在父類的某個方法上聲明了throws拋出某些異常,而在子類中重些該方法時,我們可以做以下的操作:
不處理異常(重寫方法時不聲明throws)
可僅在throws中聲明父類中聲明的部分異常
可在throws中聲明父類方法中拋出的異常的子類異常
但是不能做以下操作:
重寫方法時在throws中出聲明拋出額外的異常
重寫方法是在throws中聲明父類方法中聲明的拋出異常的父類異常
3. Java異常API3.1. RuntimeException
Java異常可以分為可檢測異常,非檢測異常
可檢測異常:可檢測異常經編譯器驗證,對於聲明拋出異常的任何方法,編譯器將強制執行處理或聲明規則,不捕捉這個異常,編譯器就通不過,不允許編譯
非檢測異常:非檢測異常不遵循處理或者聲明規則。在產生此類異常時,不一定非要採取任何適當操作,編譯器不會檢查是否已經解決了這樣一個異常
RuntimeException 類屬於非檢測異常,因為普通JVM操作引起的運行時異常隨時可能發生,此類異常一般是由特定操作引發。但這些操作在java應用程式中會頻繁出現。因此它們不受編譯器檢查與處理或聲明規則的限制 。
3.2. 常見RuntimeException
IllegalArgumentException
拋出的異常表明向方法傳遞了一個不合法或不正確的參數
NullPointerException
當應用程式試圖在需要對象的地方使用 null 時,拋出該異常
ArrayIndexOutOfBoundsException
當使用的數組下標超出數組允許範圍時,拋出該異常
ClassCastException
當試圖將對象強制轉換為不是執行個體的子類時,拋出該異常
NumberFormatException
當應用程式試圖將字串轉換成一種數實值型別,但該字串不能轉換為適當格式時,拋出該異常。
4. Exception常用API4.1. printStackTrace
Throwable中定義了一個方法可以輸出錯誤資訊,用來跟蹤例外狀況事件發生時執行堆棧的內容。該方法定義為:
void printStackTrace()
例如:
try{ …}catch(Exception e){ e.printStackTrace();//輸出執行堆棧資訊 }
4.2. getMessage
Throwable中定義了一個方法可以得到有關例外狀況事件的資訊。該方法定義為:
StringgetMessage()
例如:
try{ …}catch(Exception e){ System.out.println(e.getMessage());}
4.3. getCause
很多時候,當一個異常由另一個異常導致異常而被拋出的時候,Java庫和開放原始碼會將一種異常封裝成另一種異常。這時,日誌記錄和列印根異常就變得非常重要。Java異常類提供了 getCause()方法來檢索導致異常的原因,這些可以對異常根層次的原因提供更多的資訊。該Java實踐對代碼的調試或故障排除有很大的協助。另外,如果要把一個異常封裝成另一種異常,構造一個新異常就要傳遞源異常。
Throwable getCause()
擷取該異常出現的原因
5. 自訂Exception5.1. 自訂異常的意義
Java異常機制可以保證程式更安全和更健壯。雖然Java類庫已經提供很多可以直接處理異常的類,但是有時候為了更加精準地捕獲和處理異常以呈現更好的使用者體驗,需要開發人員自訂異常。
5.2. 繼承Exception自訂異常
建立自訂異常類,文法格式:
publicclass[自訂異常類名]extends Exception{ …}
5.3. 如何編寫構造方法
當定義好自訂異常後,我們可以通過Eclipse來自動產生相應的構造方法。
具體步驟如下:
①聲明一個類並繼承自Exception
②右鍵點擊點擊Source
③選擇Generate Constructors from Superclass
④選中父類中所有構造方法後確認產生
例如:
publicclass MyException extends Exception{publicMyException(){super();// TODO Auto-generated constructor stub}publicMyException(String message, Throwable cause){super(message, cause);// TODO Auto-generated constructor stub}publicMyException(String message){super(message);// TODO Auto-generated constructor stub}publicMyException(Throwable cause){super(cause);// TODO Auto-generated constructor stub}}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
黑馬程式員--Java基礎--異常處理