1. 程式人生 > 資訊 >駱駝官方旗艦店:工裝馬丁靴 189 元探底(京東 418 元)

駱駝官方旗艦店:工裝馬丁靴 189 元探底(京東 418 元)

異常

+-------------------------------+
|	Throwable		|
|	/	\	        |
|      /	 \	        |
|  Error	Exception	|
|                /      \	|
|		/        \	|
|	    Runtime	Other	|
+-------------------------------+
  • Runtime Exception是unchecked未受檢異常,Other是checked檢查異常。通常在程式中處理的都是受檢異常。

  • Exception類是應該被程式捕獲處理的;而Error同樣也可以被捕獲,但通常是JVM出現異常,這些嚴重的問題程式不應該捕獲。所以不能直接捕獲Throwable,而應該具體到Exception類。

受檢異常和非受檢異常

  1. 受檢異常 Other Exception

    Java 在編譯時就驗證受檢異常。 因此我們需要丟擲或者捕獲處理這些異常。

    常見的受檢異常有IOExceptionSQLExceptionParseException

    我們可以通過繼承 Exception 類來實現自定義的受檢異常

  2. 非受檢異常 Runtime Exception

    Java 不會在編譯時驗證非經受檢的異常。這類異常通常反映了程式邏輯的一些錯誤。

    不受檢我們也就不用捕獲和丟擲,但是執行時如果有錯將會丟擲異常。

    常見的是是 NullPointerExceptionArrayIndexOutOfBoundsException

    IllegalArgumentExceptionArithmeticException

    我們可以通過繼承 RuntimeException 來實現自定義的非受檢異常

  • 什麼時候使用受檢異常,什麼時候使用非受檢異常?

    “如果可以合理地期望客戶端從異常中恢復,請將其設為已檢查的異常。 如果客戶端無法從異常中恢復,請將其設為非經檢查的異常。” -Oracle

try-with-source

java7引入,我們可以在try後括號內宣告和初始化資源,執行完try塊資源將自動關閉。

  1. 資源必須實現了AutoCloseable或Closeable介面
  2. 要自動關閉,必須在括號內宣告和初始化資源
  3. 可以宣告多個資源,用分號分隔
  4. 先宣告的資源先初始化,但最後關閉

全域性異常捕獲

自從1.5開始,Java 的 Thread 類中提供了 UncaughtExceptionHandler 介面。

    @FunctionalInterface
    public interface UncaughtExceptionHandler {
        void uncaughtException(Thread t, Throwable e);
    }

    // null unless explicitly set
    private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;

    public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(
                new RuntimePermission("setDefaultUncaughtExceptionHandler")
                    );
        }

         defaultUncaughtExceptionHandler = eh;
     }

要使用java提供的全域性異常處理,我們需要實現一個 UncaughtExceptionHandler 的 Handler 類,並實現 uncaughtException 方法,該執行緒非被捕獲的異常都將在這裡處理,通常我們進行日誌記錄。然後執行緒有一個 defaultUncaughtExceptionHandler 屬性,我們要將其設定為我們實現的 Handler 類。看看具體怎麼做:

  public class Test {

      public static void main(String[] args) {

          Handler globalExceptionHandler = new Handler();
          Thread.setDefaultUncaughtExceptionHandler(globalExceptionHandler);
          System.out.println(10/0);
      }
  }

  class Handler implements Thread.UncaughtExceptionHandler {

      private static Logger LOGGER = LoggerFactory.getLogger(Handler.class);

      public void uncaughtException(Thread t, Throwable e) {
          LOGGER.info("Unhandled exception caught!");
      }
  }

Runtime異常都可以被捕獲,受檢異常也可以丟擲給它處理。

不過,這打破了就近捕獲和處理異常的規則,在很多框架中都使用了全域性異常。