1. 程式人生 > >java受檢異常與執行時異常

java受檢異常與執行時異常

正確運用異常處理機制,有助於提高程式的健壯性。
所謂程式的健壯性,就是指程式在多數情況下能夠正常執行,返回預期的正確結果;如果偶爾遇到異常情況,程式也能採取周到的解決措施。

受檢查異常表示程式可以處理的異常,如果丟擲異常的方法本身不能處理它,那麼方法呼叫者應該去處理它,從而使程式恢復執行,不至於終止程式。

例如,噴墨印表機在列印檔案時,如果紙用完或者墨水用完,就會暫停列印,等待使用者新增列印紙或更換墨盒,如果使用者添加了列印紙或更換了墨盒,就能繼續列印。 可以用OutOfPaperException類和OutOfInkException類來表示紙張用完和墨水用完這兩種異常情況,由於這些異常是可修復的,因此是受檢查異常,可以把它們定義為Exception類的子類.

public class OutOfPaperException extends Exception{…}
public class OutOfInkException extends Exception{…}

印表機的print()方法:

public void print()  
{      
 while(檔案未列印完) {  
      try {    列印一行   }   
      catch(OutOfInkException e) {     
      do  {  等待使用者更換墨盒  }    while(使用者沒有更換墨盒) } 
      catch
(OutOfPaperException e) { do { 等待使用者新增列印紙 } while(使用者沒有新增列印紙)} } }

執行時異常表示無法讓程式恢復執行的異常,導致這種異常的原因通常是由於執行了錯誤操作。一旦出現了錯誤操作,建議終止程式,因此Java編譯器不檢查這種異常。

如果程式程式碼中有錯誤,就可能導致執行時異常,如for語句的迴圈條件不正確,會導致ArrayIndexOutOfBoundsException。
執行時異常是應該儘量避免的,在程式除錯階段,遇到這種異常時,正確的做法是改程序序的設計和實現方式,修改程式中的錯誤,從而避免這種異常。捕獲它並且使程式恢復執行並不是明智的辦法,因為即使程式恢復執行,可能會導致程式的業務邏輯錯亂,導致更嚴重的異常,或者得到錯誤的執行結果

java什麼情況下必須用throws丟擲異常?
在程式中丟擲了非RuntimeException異常卻沒有對其處理(用try catch塊處理)的情況下,必須在方法頭throws該異常。

什麼情況下需要自定義異常呢?
通常情況下是程式執行狀態與使用者的預先定義的邏輯不符合,但程式並不能識別這種邏輯錯誤時需自定義異常。比如某個方法的引數只能接受0~9的數字,數字1除外,萬一使用者要是輸入了1,我們可以自定義一個異常來處理1這個意外,從而控制程式流程等。

什麼情況下捕獲異常應該立即處理呢?
比如說接收使用者輸入整型值,而使用者卻輸入了不能解析成整型的字串,這會丟擲異常,我們不應該往外拋,而應該立即處理之,提示使用者輸入合法的值,待使用者輸入合法值之後,接著往下執行程式。捕獲到異常之後一般處理辦法是輸出錯誤日誌,或者給使用者一些提示。

  • 小結

Exception異常分為:RuntimeException(執行時異常,也叫未檢查異常或不受檢查異常)和已檢查異常(或受檢查異常)。
已檢查異常 是指程式設計師已經足夠小心的檢查了他的程式碼,但是還是不能保證程式碼不出現異常;
如,程式要訪問某個檔案,但訪問時檔案不存在,這和程式本身沒有太大關係;再如,程式要進行網路連線,但執行時沒有連線網線,這些問題都是已檢查異常。

未檢查異常 一般是由程式設計師沒有細心檢查程式碼而導致的。
如空指標異常、陣列越界、型別轉換異常等都是由於程式設計師粗心大意造成的。這些異常是在編碼過程中是能夠避免的。

看到此你需要思考:我們需要處理的到底是已檢查異常還是未檢查異常?如一幢大樓執行過程中被雷擊中,這肯定是已檢查異常,但執行過程中發現有個地方四周沒有窗戶和門,這就是未檢查異常,那到底我們需要針對哪個異常進行應急預案呢?當驗收大樓時肯定政府部門要檢查你的抗震級別,消防措施等,這些措施是你在修建時必須考慮,而且要求是強制執行的,那麼這個要求就是必須處理的,如果不處理則編譯通不過。如果出現未檢查異常,那就只能加門或窗戶,即修改程式碼了。

從另外一個角度來講,已檢查異常(受檢查異常)就是受編譯器檢查的異常執行時異常,屬於RuntimeException類及子類範圍的類(以及衍生類)都屬於執行時異常。 受檢查異常,在Exception範圍內,除了執行時異常的類都是受檢查異常類,為checked exception 它們之間的區別在於: 例如在程式碼中寫了 throw new Exception(); 和 throw new RuntimeException(); 兩者都會在執行期間丟擲異常!(1)但是在編譯階段前者屬於丟擲一個受檢查異常,要求對它進行顯式的try..catch捕獲處理或者向上一層方法丟擲,否則在編譯期間就顯示錯誤! (2)後者丟擲是執行時異常,在編譯階段不予檢查,語法上不會顯示任何錯誤(throws處沒宣告不會出錯,但最好宣告)!

所以簡單的通過throw手動丟擲受檢查異常和丟擲執行時異常,前者要求顯式處理,後者不要求作出處理。
我以為的設計原則:
(1)受檢查異常如FileNotFoundException,編譯時期受檢查,提醒使用者try{}catch{}或者throw到上一層,當然你可以一直throw直至拋給虛擬機器,然而這並不是好的方式,因為對於這個異常,我們是可以進行一些處理,挽救的,比如我們可以在捕獲到異常的時候,提醒使用者”找不到檔案”,使用者就可以根據這個資訊,把相應檔案放到指定位置,從而解決問題,並不需要終止程式,或者修改程式碼。

(2)而對於非受檢查異常如ArrayIndexOutOfBoundsException(陣列越界異常),編譯時期不提供錯誤檢查,我想是因為,針對這個錯誤,使用者是無能為力的,同樣程式設計師也是部分無能為力的,你不可能通過try{}catch{}去捕獲這個異常之後,再去增加陣列容量。這時你所能做的,只能是去修改程式碼,如修改陣列容量,或換個自增的資料結構。這種執行時錯誤,只能通過在編譯階段,依靠程式設計師的小心謹慎來避免。

以上學習自百度文庫,講解的很清楚。