Java運行時異常和非運行時異常


 

 

 

 

 

 

 

 

1.Java異常機制

Java把異常當做對象來處理,並定義一個基類java.lang.Throwable作為所有異常的超類。Java中的異常分為兩大類:錯誤Error和異常Exception,Java異常體系結構如下圖所示:

圖片來源:http://blog.csdn.NET/wuwenxiang91322/article/details/10346337

 

2.Throwable

Throwable類是所有異常或錯誤的超類,它有兩個子類:Error和Exception,分別表示錯誤和異常。其中異常Exception分為運行時異常(RuntimeException)和非運行時異常,也稱之為不檢查異常(Unchecked Exception)和檢查異常(Checked Exception)。

 

3.Error

一般是指java虛擬機相關的問題,如系統崩潰、虛擬機出錯誤、動態鏈接失敗等,這種錯誤無法恢復或不可能捕獲,將導致應用程序中斷,通常應用程序無法處理這些錯誤,因此應用程序不應該捕獲Error對象,也無須在其throws子句中聲明該方法拋出任何Error或其子類。

 

4.可查異常和不可查異常

通常,Java的異常(包括Exception和Error)分為可查的異常(checked exceptions)和不可查的異常(unchecked exceptions)。
可查異常(編譯器要求必須處置的異常):正確的程序在運行中,很容易出現的、情理可容的異常狀況。可查異常雖然是異常狀況,但在一定程度上它的發生是可以預計的,而且一旦發生這種異常狀況,就必須采取某種方式進行處理。
除了RuntimeException及其子類以外,其他的Exception類及其子類都屬於可查異常。這種異常的特點是Java編譯器會檢查它,也就是說,當程序中可能出現這類異常,要么用try-catch語句捕獲它,要么用throws子句聲明拋出它,否則編譯不會通過。
不可查異常(編譯器不要求強制處置的異常):包括運行時異常(RuntimeException與其子類)和錯誤(Error)。

如果使用throw在方法體中拋出可查異常,則需要在方法頭部聲明方法可能拋出的異常類型。程序會在throw語句后立即終止,它后面的語句執行不到,然后在包含它的所有try塊中(可能在上層調用函數中)從里向外尋找含有與其匹配的catch子句的try塊。

 

5.運行時異常和非運行時異常

(1)運行時異常都是RuntimeException類及其子類異常,如NullPointerException、IndexOutOfBoundsException等,這些異常是不檢查異常,程序中可以選擇捕獲處理,也可以不處理。這些異常一般是由程序邏輯錯誤引起的,程序應該從邏輯角度盡可能避免這類異常的發生。

當出現RuntimeException的時候,我們可以不處理。當出現這樣的異常時,總是由虛擬機接管。比如:我們從來沒有人去處理過NullPointerException異常,它就是運行時異常,並且這種異常還是最常見的異常之一。 
出現運行時異常后,如果沒有捕獲處理這個異常(即沒有catch),系統會把異常一直往上層拋,一直到最上層,如果是多線程就由Thread.run()拋出,如果是單線程就被main()拋出。拋出之后,如果是線程,這個線程也就退出了。如果是主程序拋出的異常,那么這整個程序也就退出了。運行時異常是Exception的子類,也有一般異常的特點,是可以被catch塊處理的。只不過往往我們不對他處理罷了。也就是說,你如果不對運行時異常進行處理,那么出現運行時異常之后,要么是線程中止,要么是主程序終止。 
如果不想終止,則必須捕獲所有的運行時異常,決不讓這個處理線程退出。隊列里面出現異常數據了,正常的處理應該是把異常數據舍棄,然后記錄日志。不應該由於異常數據而影響下面對正常數據的處理。


(2)非運行時異常是RuntimeException以外的異常,類型上都屬於Exception類及其子類。如IOException、SQLException等以及用戶自定義的Exception異常。對於這種異常,JAVA編譯器強制要求我們必需對出現的這些異常進行catch並處理,否則程序就不能編譯通過。所以,面對這種異常不管我們是否願意,只能自己去寫一大堆catch塊去處理可能的異常。

 

6.finally關鍵字

來看看下面這個test1()方法:

 

[java]  view plain  copy
 
  1. public int test1() {  
  2.         try {  
  3.             return 1;  
  4.         } finally {  
  5.             return 2;  
  6.         }  
  7.     }  

方法test1將返回2;

 

怎么解釋呢?再來看看下面這個test2()方法:

 

[java]  view plain  copy
 
  1. public int test2() {  
  2.         int i = 1;  
  3.         try {  
  4.             System.out.println("try語句塊中");  
  5.             return 1;  
  6.         } finally {  
  7.             System.out.println("finally語句塊中");  
  8.             return 2;  
  9.         }  
  10.   
  11.     }  

運行結果是:

 

try語句塊中
finally語句塊中
2

從運行結果中可以發現,try中的return語句調用的函數先於finally中調用的函數執行,也就是說return語句先執行,finally語句后執行,所以,返回的結果是2。return並不是讓函數馬上返回,而是return語句執行后,將把返回結果放置進函數棧中,此時函數並不是馬上返回,它要執行finally語句后才真正開始返回。


常見RuntimeException:

ArrayStoreException                試圖將錯誤類型的對象存儲到一個對象數組時拋出的異常
ClassCastException                試圖將對象強制轉換為不是實例的子類時,拋出該異常
IllegalArgumentException         拋出的異常表明向方法傳遞了一個不合法或不正確的參數
IndexOutOfBoundsException   指示某排序索引(例如對數組、字符串或向量的排序)超出范圍時拋出
NoSuchElementException       表明枚舉中沒有更多的元素
NullPointerException                當應用程序試圖在需要對象的地方使用 null 時,拋出該異常

 

參考資料:http://blog.csdn.net/wuwenxiang91322/article/details/10346337

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM