Java中Error和Exception的異同以及執行時異常(Runtime exception)與檢查型異常(checked exception)的區別

你的龍兒發表於2020-05-13

一:Error和Exception的基本概念:

 

首先Exception和Error都是繼承於Throwable 類,在 Java 中只有 Throwable 型別的例項才可以被丟擲(throw)或者捕獲(catch),它是異常處理機制的基本組成型別。

Exception 和 Error 體現了 Java 平臺設計者對不同異常情況的分類,Exception和Error體現了JAVA這門語言對於異常處理的兩種方式。

Exception 是程式正常執行過程中可以預料到的意外情況,並且應該被開發者捕獲,進行相應的處理。

 

Error是java程式執行中不可預料的異常情況(正常情況下不大可能出現的情況),這種異常發生以後,會直接導致JVM不可處理或者不可恢復的情況。所以這種異常不可能抓取到,比如OutOfMemoryError、NoClassDefFoundError等。【表示由JVM所偵測到的無法預期的錯誤,由於這是屬於JVM層次的嚴重錯誤 ,導致JVM無法繼續執行,因此,這是不可捕捉到的,無法採取任何恢復的操作,頂多只能顯示錯誤資訊。 Error類體系描述了Java執行系統中的內部錯誤以及資源耗盡的情形.應用程式不應該丟擲這種型別的物件(一般是由虛擬機器丟擲).假如出現這種錯誤,除了盡力使程式安全退出外,在其他方面是無能為力的。】

 

其中的Exception又分為檢查性異常(checked)和非檢查性異常(unchecked)。兩個根本的區別在於,檢查性異常 必須在編寫程式碼時,使用try catch捕獲(比如:IOException異常)。非檢查性異常 在程式碼編寫使,可以忽略捕獲操作(比如:ArrayIndexOutOfBoundsException),這種異常是在程式碼編寫或者使用過程中通過規範可以避免發生的,具體根據需要來判斷是否需要捕獲,並不會在編譯器強制要求。

切記,Error是Throw不是Exception 。

 

二者的不同之處(小總結):

Exception
1.可以是可被控制(checked) 或不可控制的(unchecked)。
2.表示一個由程式設計師導致的錯誤。
3.應該在應用程式級被處理。
Error:
1.總是不可控制的(unchecked)。
2.經常用來用於表示系統錯誤或低層資源的錯誤。
3.如何可能的話,應該在系統級被捕捉。

 

如下是常見的 Error 和 Exception:

1)執行時異常(RuntimeException)也稱 【非檢查型異常 UncheckedException】

  • NullPropagation:空指標異常;
  • ClassCastException:型別強制轉換異常
  • IllegalArgumentException:傳遞非法引數異常
  • IndexOutOfBoundsException:下標越界異常
  • NumberFormatException:數字格式異常
  • ArrayIndexOutOfBoundsException: 陣列越界異常
  • ArrayStoreException: 資料儲存異常,運算元組時型別不一致
  • AruthmeticException: (算術異常)
  • BufferOverflowException: (緩衝區溢位異常)


2)非執行時異常(CheckedException)也稱 【檢查型異常】:

  • ClassNotFoundException:找不到指定 class 的異常
  • IOException:IO 操作異常
  • FileNotFoundException:檔案不存在異常
  • SQLException:SQL語句異常
  • InterruptedException: (中斷異常-呼叫執行緒睡眠時候)


3)錯誤(Error):

  • NoClassDefFoundError:找不到 class 定義異常
  • StackOverflowError:深遞迴導致棧被耗盡而丟擲的異常
  • OutOfMemoryError:記憶體溢位異常

eg(程式碼示例01)

下面程式碼會導致 Java 堆疊溢位錯誤。

/ 通過無限遞迴演示堆疊溢位錯誤
class StackOverflow {
    public static void test(int i) {
        if (i == 0) {
            return;
        } else {
            test(i++);
        }
    }
}
public class ErrorEg {
    public static void main(String[] args) {
        // 執行StackOverflow方法
        StackOverflow.test(5);
    }
}

執行輸出為:

Exception in thread "main" java.lang.StackOverflowError
    at ch11.StackOverflow.test(ErrorEg.java:9)
    at ch11.StackOverflow.test(ErrorEg.java:9)
    at ch11.StackOverflow.test(ErrorEg.java:9)
    at ch11.StackOverflow.test(ErrorEg.java:9)

上面程式碼通過無限遞迴呼叫最終引發了 java.lang.StackOverflowError 錯誤。

二:Error和Exception的使用場景:

eg01:經典的面試題目: 就是 NoClassDefFoundError 和 ClassNotFoundException 有什麼區別

區別一: NoClassDefFoundError它是Error,
ClassNotFoundException是Exception。 區別二:NoClassDefFoundError是JVM執行時通過classpath載入類時,找不到對應的類而丟擲的錯誤。
ClassNotFoundException是在編譯過程中如果可能出現此異常,在編譯過程中必須將ClassNotFoundException異常丟擲! NoClassDefFoundError發生場景如下
1、類依賴的class或者jar不存在 (簡單說就是maven生成執行包後被篡改) 2、類檔案存在,但是存在不同的域中 (簡單說就是引入的類不在對應的包下) 3、大小寫問題,javac編譯的時候是無視大小的,很有可能你編譯出來的class檔案就與想要的不一樣!這個沒有做驗證 ClassNotFoundException發生場景如下: 1、呼叫class的forName方法時,找不到指定的類 2、ClassLoader 中的 findSystemClass() 方法時,找不到指定的類 舉例說明如下: Class.forName("abc"); 比如abc這個類不存專案中,程式碼編寫時,就會提示此異常是檢查性異常,比如將此異常丟擲。

三:執行時異常(Runtime exception)與檢查型異常(checked exception)的區別:

 

 Java提供了兩類主要的異常:runtime exception和checked exception。

1:checked (檢查型異常)也就是我們經常遇到的IO異常,以及SQL異常都是這種異常。編譯器要檢查這類異常,檢查的目的一方面是因為該類異常的發生難以避免,
另一方面就是讓開發者去解決掉這類異常,所以稱為必須處理(try ...catch)的異常。
如果不處理這類異常,整合開發環境中的編譯器一般會給出錯誤提示。

              注意:如果一個方法沒有捕獲一個檢查性異常,那麼該方法必須使用 throws 關鍵字來宣告。throws 關鍵字放在方法名的後邊,eg:  方法名() throws  IOExecption。

 

2:runtime exception(執行時異常),編譯器不會檢查這類異常,不檢查的則開發者在程式碼的編輯編譯階段就不是必須處理,這類異常一般可以避免,因此無需處理(try ...catch),

  如果不處理這類異常,整合開發環境中的編譯器也不會給出錯誤提示。    當出現這樣的異常時,總是由虛擬機器接管。

    eg:我們從來沒有人去處理過NullPointerException異常,它就是執行時異常,並且這種異常還是最常見的異常之一。 


 
 

 

相關文章