問題:Exception、Error、運行時異常與一般異常有何異同?
解析:首先我應該知道,在 Java 中 Throwable 是所以程序錯誤處理的父類,它有兩個子類:Error 和 Exception。
Error:表示由JVM 所偵測到的無法預期的錯誤,由于這是屬于 JVM 層次的嚴重錯誤,導致 JVM 無法繼續(xù)執(zhí)行,因此,這是不可捕捉的,無法采取任何恢復的操作,頂多只能顯示錯誤信息。Error 類體系描述了 Java 運行系統(tǒng)中的內部錯誤以及資源耗盡的情形,應用程序不應該拋出這種類型的對象(一般由虛擬機拋出)。假如出現(xiàn)這種錯誤,除了盡力使得程序安全推出外,在其他方面是無能為力的。
Exception :表示可恢復的例外,這是可補足的。
一般異常:定義方法時必須聲明所有可能會拋出的checked exception;在調用這個方法時,必須捕獲它的checked exception,不然就得把它的exception傳遞下去;checked exception是從java.lang.Exception類衍生出來的。
Java 提供了兩類主要異常:runtime exception和 checked exception。checked 異常也就是經常遇到的 IO 異常以及 SQL 異常都是這種異常。對于這種異常,Java 編譯器強制要求我們必須對出現(xiàn)的這些異常進行 catch。所以,面對這種異常不管我們是否愿意,只能自己去寫一大堆 catch 塊去處理可能的異常。這類異常一般是外部錯誤,例如試圖從文件尾后讀取數(shù)據(jù)錯誤,這并不是程序本身的錯誤,而是在應用環(huán)境中出現(xiàn)的外部錯誤。
但另外一種異常:runtime exception,也叫運行時異常,我們可以不處理。當出現(xiàn)這樣的異常時,總是由虛擬機接管。比如:我們從來沒有人去處理過 NullPointerException 異常,它就是運行時異常,并且,這種異常還是最常見的異常之一。RuntimeException 體系包括錯誤的類型轉換、數(shù)組越界訪問和試圖訪問空指針等等。處理 RuntimeException 的原則是:假如出現(xiàn) RuntimeException,那么一定是程序員的錯誤,例如,可以通過檢查數(shù)組小標和數(shù)組邊界來避免越界訪問異常。
出現(xiàn)運行時異常后,系統(tǒng)會把異常一直往上層拋,一直遇到處理代碼。如果沒有處理塊,到最上層,如果是多線程就由 Thread.run() 拋出,如果是單線程就被 main() 拋出。拋出之后,如果是線程,這個線程也就推出了。如果主程序拋出的異常,那么這個程序也就退出了。運行時異常是 Exception 的子類,也就是一般異常的特點,也可以被catch 塊處理的。只不夠往往我們不處理罷了。也就是說,我如果不對運行時異常進行處理,那么出現(xiàn)運行時異常之后,要門線程終止,要么時主程序終止。
如果不想終止,則必須捕捉所有的運行時異常,決不讓這個線程退出。隊列里面出現(xiàn)異常數(shù)據(jù)了,正常的處理應該是把異常數(shù)據(jù)舍棄,然后記錄日志。不應該由于異常數(shù)據(jù)而影響下面對正常數(shù)據(jù)的處理。在這個場景這樣的處理可能是一個比較好的應用,但并不代表在所有的場景都應該如此。如果在其它場景,遇到了一些錯誤,如果推出程序比較好,這時你就可以不太理會運行時異常,或者是通過對異常的處理顯示的控制程序退出。
異常處理的目標之一就是為了把程序從異常中恢復出來。