Java捕獲非檢查異常----UncaughtExceptionHandler的使用

今天在看Zookeeper源碼的時候發如今其源碼中使用到了UncaughtExceptionHandler處理非檢查異常,關鍵是剛開始看的時候我不會呀!因此得學習呀!因此便出現了下文。java

1、Java的異常類型

這是一張Java異常體系大體圖:程序員

從大致上說,Java中的異常分爲兩種:數據庫

  • 一、非檢查異常apache

    非檢查異常爲ErrorRuntimeException及其子類,javac在編譯時,不會提示和發現這樣的異常,不要求在程序處理這些異常。因此若是願意,咱們能夠編寫代碼處理(使用try…catch…finally)這樣的異常,也能夠不處理。對於這些異常,咱們應該修正代碼,而不是去經過異常處理器處理 。這樣的異常發生的緣由多半是代碼寫的有問題。如除0錯誤ArithmeticException,錯誤的強制類型轉換錯誤ClassCastException,數組索引越界ArrayIndexOutOfBoundsException,使用了空對象NullPointerException等等數組

  • 二、檢查異常bash

    檢查異常則是除了ErrorRuntimeException的其它異常。javac強制要求程序員爲這樣的異常作預備處理工做(使用try…catch…finally或者throws)。在方法中要麼用try-catch語句捕獲它並處理,要麼用throws子句聲明拋出它,不然編譯不會經過。這樣的異常通常是由程序的運行環境致使的。由於程序可能被運行在各類未知的環境下,而程序員沒法干預用戶如何使用他編寫的程序,因而程序員就應該爲這樣的異常時刻準備着。如SQLException , IOException,ClassNotFoundException 等。多線程

總結下:ide

  • 一、檢查異常,非檢查異常均可以使用try…catch…finally塊捕獲異常
  • 二、非檢查異常屬於運行時異常,編譯器不會提示你進行捕獲

爲何我要進行總結呢?下面我將說到!學習

2、UncaughtExceptionHandler的使用

不少時候咱們寫完代碼,運行以後總是會報空指針異常,咱們卻沒發現應該去捕獲它。特別是在多線程環境中,線程類Threadrun()方法是沒有拋出任何異常信息的,若是在run()方法中報一個空指針異常,咱們卻沒有捕獲它,那後果將會是使線程中斷,線程中斷可能並非咱們想看到的結果。spa

最可氣的是,子線程拋出的異常信息,在其主線程一樣是捕獲不到的。下面舉例子演示下:

public class NoCaughtThread {

public static void main(String[] args) {
	// 捕獲不到
	try {
		Thread thread = new Thread(new Task());
		thread.start();
	} catch (Exception e) {
		e.printStackTrace();
	}
    }
}

class Task implements Runnable {

@Override
public void run() {
	throw new NullPointerException();
    }
}
複製代碼

程序運行結果:

Exception in thread "Thread-0" java.lang.NullPointerException
	at org.apache.zookeeper.server.quorum.Task.run(NoCaughtThread.java:21)
	at java.lang.Thread.run(Unknown Source)
複製代碼

爲了處理這些未捕獲的異常,jdk自帶了UncaughtExceptionHandler類進行處理,實例以下:

import java.lang.Thread.UncaughtExceptionHandler;

public class NoCaughtThread {

public static void main(String[] args) {
	// 設置未捕獲異常處理器,這裏是默認的,固然你能夠本身新建一個類,而後實現UncaughtExceptionHandler接口便可
	Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {

		@Override
		public void uncaughtException(Thread t, Throwable e) {
			System.err.println("程序拋出了一個異常,異常類型爲 : " + e);
		}
	});
	Thread thread = new Thread(new Task());
	thread.start();
    }
}

class Task implements Runnable {

@Override
public void run() {
	throw new NullPointerException();
    }
}
複製代碼

程序輸出:

程序拋出了一個異常,異常類型爲 : java.lang.NullPointerException
複製代碼

3、總結

總結一下,歸根到底,我以爲之因此須要使用到UncaughtExceptionHandler,不少狀況下都是由於咱們本身代碼寫的很差,不夠嚴謹,或者說咱們在寫代碼的時候沒有考慮周到。好比最多見的就是拋出空指針NullPointerException,請看下面代碼:

Map<String, String> map = null;
System.err.println(map.get("name"));
複製代碼

上面的代碼一定拋出空指針異常,你可能會說,哇,誰這麼笨,這麼明顯聲明map=null,好,爲了使你信服,我決定打個響指:

// 從數據庫查找一個用戶
User user = userDao.getUser(12);
System.err.println(user.getUserName("name"));
複製代碼

能夠看出,若是usernull,則一定也是拋出空指針異常。不少不少非檢查異常咱們都須要儘可能避免,在編寫代碼的時候多考慮是否會出現空指針,是否會出現數組越界等等狀況。

相關文章
相關標籤/搜索