Java Exception Handling -java異常處理
java中的異常 異常是程式
在編譯時間或者
運行時出現的意想不到的情境,比如在書寫java代碼時候不遵守java文法規則會導致編譯失敗,運算元組,下標越界的運行時異常等等。
當異常發生時會導致程式異常退出,為了避免程式異常退出,我們必須對出現的某些異常處理,讓程式繼續執行下去,俗稱“
異常恢複”。
java中異常的出現 異常的出現一般有以下情況:
throw 自訂異常
代碼在異常情境下執行拋出的異常,如數組越界異常、IOException, ArithmeticException, SocketException等等。
JVM本身在運行時拋出的異常,比如記憶體溢出異常等等。這類異常稱之為非同步異常,我們程式不可能處理它。
java異常處理
當程式運行時出現異常的時候,我們對異常現象的捕獲並試圖讓程式繼續啟動並執行過程,我們稱之為異常處理。異常處理改變了程式的執行流程,即當程式出現異常時,即A計劃執行失敗,我們就執行備用B計劃,使得業務繼續。 哪些異常我們可以處理 運行時出現的某些異常,即使我們處理,也不能讓程式恢複,比如之前的非同步異常,記憶體溢出錯誤等。Error類異常是不能讓程式繼續執行的,Exception類我們可以捕獲,處理異常情況,使得程式繼續執行。我們一般不會捕獲Error異常,而是捕獲Exception異常。
異常處理關鍵字 try 塊 catch 塊 finally 塊 throw關鍵字 throws關鍵字 Try-with-Resources
java異常繼承關係
java中比較重要的也是最基礎的異常類有Throwable,Error,Exception和RuntimeException。
Throwable類是所有異常類的父類,它不能直接被我們拋出,而且是受編譯器檢查的-受檢異常(compiler checked )。
Error類是Throwable的子類,代表了不可恢複的所有異常。當出現了Error異常時候,即使我們對他們進行異常處理,程式也會異常退出。Error類及其子類也被稱之為非同步異常。Error類不受編譯器檢查的-非受檢異常。
Exception類是Throwable的子類,Exception類及其子類是可恢複異常。Exception是受編譯器檢查的-受檢異常。
RuntimeException類是Exception的子類,它及它的子類不受編譯器檢查的-非受檢異常。一般情況下,RuntimeException可以在程式中避免,比如NullPointerException, ArithmeticException, ArrayIndexOutOfBoundException等,我們在異常發生之前可以用代碼判斷,從而避免異常的出現。
異常的生命週期 當異常發生時,如果程式沒有處理,異常就會從當前棧一直往棧頂方向拋出,去尋找例外處理常式,如果沒找到,最終就會被JVM停止程式執行處理,並且stack trace 會預設有system.err輸出。
如果你要儲存異常堆棧資訊,我們可以設定預設異常處理handler:
Thread.setDefaultUncaughtExceptionHandler((thread, ex) -> {Record the exception}) 當我們catch了異常時,我們一般不會忽略異常即catch塊是空的,最起碼你得必須列印出異常堆棧資訊:
try {Class<?> cl = Class.forName(className);…} catch (ClassNotFoundException ex) {ex.printStackTrace();}
如果你要儲存堆棧資訊,可以把異常堆棧資訊轉換成字串:
ByteArrayOutputStream out = new ByteArrayOutputStream();ex.printStackTrace(out);String description = out.toString();
如果要細緻的分析堆棧,我們可以用:
StackTraceElement[] frames = ex.getStackTrace();
得到 StackTraceElement執行個體來具體分析,具體api參考javadoc。
package com.doctor.commons;import java.io.IOException;import java.io.PrintWriter;import java.io.StringWriter;import com.doctor.beaver.annotation.ThreadSafe;/** * @author sdcuike * <p> * Created on 2016年9月27日<br/> */@ThreadSafepublic final class ExceptionUtils { public static String printStackTraceToString(final Throwable t) throws IOException { try (StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw);) { t.printStackTrace(pw); pw.flush(); sw.flush(); return sw.toString(); } } public static String printFullStackTraceToString(final Throwable t) throws IOException { try (StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw);) { Throwable caseT = t; while (caseT != null) { caseT.printStackTrace(pw); caseT = caseT.getCause(); } pw.flush(); sw.flush(); return sw.toString(); } }}
Checked and Unchecked Exception-受檢異常和非受檢異常 前文提供過這些概念,
受檢異常是受java編譯檢查的異常,受檢異常如果沒被處理,編譯器會報錯。Throwable和Exception類及其子類都是受檢異常。
受檢異常必須遵守Catch or Declare Rule ,要麼處理,要麼繼續向上層調用棧拋出此異常。
受檢異常必須try catch 或者throws關鍵字處理。 非受檢異常是不受java編譯器檢查的異常,也被稱之為運行時異常。從RuntimeException 和Error繼承的子類都是非受檢查異常。
異常體系中受檢異常與非受檢異常:深顏色的代表受檢異常,淺顏色的代表非受檢異常。
圖來源:absolute java 6th edition
----Walter Savitch © Pearson Education Limited 2016
方法重載異常處理規則
父類方法沒有throws任何異常時,子類不能throws受檢異常,但可以throws非受檢異常。
父類方法throws異常時,子類不必throws任何異常,或者throws的異常必須是同類型或者子類(即刪除或替換異常規則)。
Error和 RuntimeException 類及其他們的子類應該不出現在throws列表中。
參考:http://www.tutorialspoint.com/java/java_exceptions.htm
http://tutorials.jenkov.com/java-exception-handling/index.html
http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
http://www.javaworld.com/article/2076700/core-java/exceptions-in-java.html
Java 8 Exception Handling Develop Reliable Java Applications (Black Book Series) - Mahavir DS Rathore
(https://yunpan.cn/ckzJdHGh8I78b 訪問密碼 e580)