国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

解析Java中所有錯誤和異常的父類java.lang.Throwable

2019-11-26 14:30:24
字體:
來源:轉載
供稿:網友

在java語言中,錯誤類的基類是java.lang.Error,異常類的基類是java.lang.Exception。
1)相同點:java.lang.Error和java.lang.Exception都是java.lang.Throwable的子類,因此java.lang.Error和java.lang.Exception自身及其子類都可以作為throw的使用對象,如:throw new MyError();和throw new MyException();其中,MyError類是java.lang.Error的子類,MyException類是java.lang.Exception的子類。
2)不同點:java.lang.Error自身及其子類不需要try-catch語句的支持,可在任何時候將返回方法,如下面的方法定義:

public String myMethod() { throw new MyError(); } 

其中MyError類是java.lang.Error類的子類。
java.lang.Exception自身及其子類需要try-catch語句的支持,如下的方法定義是錯誤的:

public String myMethod() { throw new MyException(); } 

正確的方法定義如下:

public String myMethod() throws MyException { throw new MyException(); } 

其中MyException類是java.lang.Exception的子類。

JAVA異常是在java程序運行的時候遇到非正常的情況而創(chuàng)建的對象,它封裝了異常信息,java異常的根類為java.lang.Throwable,整個類有兩個直接子類java.lang.Error和java.lang.Exception.Error是程序本身無法恢復的嚴重錯誤.Exception則表示可以被程序捕獲并處理的異常錯誤.JVM用方法調用棧來跟蹤每個線程中一系列的方法調用過程,該棧保存了每個調用方法的本地信息.對于獨立的JAVA程序,可以一直到該程序的main方法.當一個新方法被調用的時候,JVM把描述該方法的棧結構置入棧頂,位于棧頂的方法為正確執(zhí)行的方法.當一個JAVA方法正常執(zhí)行完畢,JVM回從調用棧中彈處該方法的棧結構,然后繼續(xù)處理前一個方法.如果java方法在執(zhí)行代碼的過程中拋出異常,JVM必須找到能捕獲異常的catch塊代碼.它首先查看當前方法是否存在這樣的catch代碼塊,如果存在就執(zhí)行該 catch代碼塊,否則JVM回調用棧中彈處該方法的棧結構,繼續(xù)到前一個方法中查找合適的catch代碼塊.最后如果JVM向上追到了main()方法,也就是一直把異常拋給了main()方法,仍然沒有找到該異常處理的代碼塊,該線程就會異常終止,如果該線程是主線程,應用程序也隨之終止,此時 JVM將把異常直接拋給用戶,在用戶終端上會看到原始的異常信息.

Java.lang.throwable源代碼解析

package java.lang; import java.io.*; /** * * Throwable是所有Error和Exceptiong的父類 * 注意它有四個構造函數: * Throwable() * Throwable(String message) * Throwable(Throwable cause) * Throwable(String message, Throwable cause) * */ public class Throwable implements Serializable {   private static final long serialVersionUID = -3042686055658047285L;    /**   * Native code saves some indication of the stack backtrace in this slot.   */   private transient Object backtrace;    /**   * 描述此異常的信息   */   private String detailMessage;    /**   * 表示當前異常由那個Throwable引起   * 如果為null表示此異常不是由其他Throwable引起的   * 如果此對象與自己相同,表明此異常的起因對象還沒有被初始化   */   private Throwable cause = this;    /**   * 描述異常軌跡的數組   */   private StackTraceElement[] stackTrace;    /**   * 構造函數,起因對象沒有被初始化可以在以后使用initCause進行初始化   * fillInStackTrace可以用來初始化它的異常軌跡的數組   */   public Throwable() {    fillInStackTrace();   }    /**   * 構造函數   */   public Throwable(String message) {    //填充異常軌跡數組    fillInStackTrace();    //初始化異常描述信息    detailMessage = message;   }    /**   * 構造函數,cause表示起因對象   */   public Throwable(String message, Throwable cause) {    fillInStackTrace();    detailMessage = message;    this.cause = cause;   }    /**   * 構造函數   */   public Throwable(Throwable cause) {    fillInStackTrace();    detailMessage = (cause==null ? null : cause.toString());    this.cause = cause;   }    /**   * 獲取詳細信息   */   public String getMessage() {    return detailMessage;   }    /**   * 獲取詳細信息   */   public String getLocalizedMessage() {    return getMessage();   }    /**   * 獲取起因對象   */   public Throwable getCause() {    return (cause==this ? null : cause);   }    /**   * 初始化起因對象,這個方法只能在未被初始化的情況下調用一次   */   public synchronized Throwable initCause(Throwable cause) {    //如果不是未初始化狀態(tài)則拋出異常    if (this.cause != this)     throw new IllegalStateException("Can't overwrite cause");       //要設置的起因對象與自身相等則拋出異常    if (cause == this)     throw new IllegalArgumentException("Self-causation not permitted");       //設置起因對象    this.cause = cause;    //返回設置的起因的對象    return this;   }    /**   * 字符串表示形式   */   public String toString() {     String s = getClass().getName();      String message = getLocalizedMessage();     return (message != null) ? (s + ": " + message) : s;   }    /**   * 打印出錯誤軌跡   */   public void printStackTrace() {    printStackTrace(System.err);   }    /**   * 打印出錯誤軌跡   */   public void printStackTrace(PrintStream s) {    synchronized (s) {    //調用當前對象的toString方法     s.println(this);    //獲取異常軌跡數組     StackTraceElement[] trace = getOurStackTrace();        //打印出每個元素的字符串表示     for (int i=0; i < trace.length; i++)     s.println("/tat " + trace[i]);     //獲取起因對象     Throwable ourCause = getCause();        //遞歸的打印出起因對象的信息     if (ourCause != null)     ourCause.printStackTraceAsCause(s, trace);    }   }    /**   * 打印起因對象的信息   * @param s 打印的流   * @param causedTrace 有此對象引起的異常的異常軌跡   */   private void printStackTraceAsCause(PrintStream s,            StackTraceElement[] causedTrace)   {    //獲得當前的異常軌跡    StackTraceElement[] trace = getOurStackTrace();    //m為當前異常軌跡數組的最后一個元素位置,    //n為當前對象引起的異常的異常軌跡數組的最后一個元素    int m = trace.length-1, n = causedTrace.length-1;    //分別從兩個數組的后面做循環(huán),如果相等則一直循環(huán),直到不等或數組到頭    while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {     m--; n--;    }       //相同的個數    int framesInCommon = trace.length - 1 - m;       //打印出不同的錯誤軌跡    s.println("Caused by: " + this);    for (int i=0; i <= m; i++)     s.println("/tat " + trace[i]);    //如果有相同的則打印出相同的個數    if (framesInCommon != 0)     s.println("/t... " + framesInCommon + " more");     //獲得此對象的起因對象,并遞歸打印出信息    Throwable ourCause = getCause();    if (ourCause != null)     ourCause.printStackTraceAsCause(s, trace);   }    /**   * 打印出錯誤軌跡   */   public void printStackTrace(PrintWriter s) {    synchronized (s) {     s.println(this);     StackTraceElement[] trace = getOurStackTrace();     for (int i=0; i < trace.length; i++)      s.println("/tat " + trace[i]);      Throwable ourCause = getCause();     if (ourCause != null)      ourCause.printStackTraceAsCause(s, trace);    }   }    /**   * 打印起因對象的信息   */   private void printStackTraceAsCause(PrintWriter s,            StackTraceElement[] causedTrace)   {    // assert Thread.holdsLock(s);     // Compute number of frames in common between this and caused    StackTraceElement[] trace = getOurStackTrace();    int m = trace.length-1, n = causedTrace.length-1;    while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {     m--; n--;    }    int framesInCommon = trace.length - 1 - m;     s.println("Caused by: " + this);    for (int i=0; i <= m; i++)     s.println("/tat " + trace[i]);    if (framesInCommon != 0)     s.println("/t... " + framesInCommon + " more");     // Recurse if we have a cause    Throwable ourCause = getCause();    if (ourCause != null)     ourCause.printStackTraceAsCause(s, trace);   }    /**   * 填充異常軌跡   */   public synchronized native Throwable fillInStackTrace();    /**   * 返回當前的異常軌跡的拷貝   */   public StackTraceElement[] getStackTrace() {    return (StackTraceElement[]) getOurStackTrace().clone();   }      /**   * 獲取當前的異常軌跡   */   private synchronized StackTraceElement[] getOurStackTrace() {    //如果第一次調用此方法則初始化異常軌跡數組    if (stackTrace == null) {    //獲得異常軌跡深度     int depth = getStackTraceDepth();    //創(chuàng)建新的異常軌跡數組,并填充它     stackTrace = new StackTraceElement[depth];        for (int i=0; i < depth; i++)     stackTrace[i] = getStackTraceElement(i);//獲取指定位標的異常軌跡    }       return stackTrace;   }    /**   * 設置異常軌跡   */   public void setStackTrace(StackTraceElement[] stackTrace) {    //拷貝設置參數    StackTraceElement[] defensiveCopy =     (StackTraceElement[]) stackTrace.clone();       //如果設置參數有空元素則拋出異常    for (int i = 0; i < defensiveCopy.length; i++)     if (defensiveCopy[i] == null)      throw new NullPointerException("stackTrace[" + i + "]");     //設置當前對象的異常軌跡    this.stackTrace = defensiveCopy;   }    /**   * 異常軌跡的深度,0表示無法獲得   */   private native int getStackTraceDepth();    /**   * 獲取指定位標的異常軌跡   */   private native StackTraceElement getStackTraceElement(int index);      private synchronized void writeObject(java.io.ObjectOutputStream s)    throws IOException   {    getOurStackTrace();    s.defaultWriteObject();   } } 

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 朝阳县| 泰来县| 德钦县| 永清县| 福贡县| 万安县| 广汉市| 连云港市| 景洪市| 左云县| 十堰市| 宜章县| 九寨沟县| 马山县| 江山市| 基隆市| 丹寨县| 环江| 五大连池市| SHOW| 莱阳市| 紫阳县| 元氏县| 托克托县| 成武县| 从江县| 上蔡县| 平塘县| 南阳市| 齐齐哈尔市| 莒南县| 肇东市| 上栗县| 全南县| 洞头县| 巫溪县| 灵寿县| 平湖市| 额敏县| 岳池县| 威海市|