1. 程式人生 > >Java運行時異常和非運行時異常

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

try-catch color 表示 finally mar 相關 strong AS str

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()方法:

public int test1() {  
        try {  
            return 1;  
        } finally {  
            return 2;  
        }  
    } 

方法test1將返回2;

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

public int test2() {  
        int i = 1;  
        try {  
            System.out.println("try語句塊中");  
            return 1;  
        } finally {  
            System.out.println("finally語句塊中");  
            return 2;  
        }  
  
    }  

運行結果是:

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

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