程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 解析Java中一切毛病和異常的父類java.lang.Throwable

解析Java中一切毛病和異常的父類java.lang.Throwable

編輯:關於JAVA

解析Java中一切毛病和異常的父類java.lang.Throwable。本站提示廣大學習愛好者:(解析Java中一切毛病和異常的父類java.lang.Throwable)文章只能為提供參考,不一定能成為您想要的結果。以下是解析Java中一切毛病和異常的父類java.lang.Throwable正文


在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法式運轉的時刻碰到非正常的情形而創立的對象,它封裝了異常信息,java異常的根類為java.lang.Throwable,全部類有兩個直接子類java.lang.Error和java.lang.Exception.Error是法式自己沒法恢復的嚴重毛病.Exception則表現可以被法式捕捉並處置的異常毛病.JVM用辦法挪用棧來跟蹤每一個線程中一系列的辦法挪用進程,該棧保留了每一個挪用辦法的當地信息.關於自力的JAVA法式,可以一向到該法式的main辦法.當一個新辦法被挪用的時刻,JVM把描寫該辦法的棧構造置入棧頂,位於棧頂的辦法為准確履行的辦法.當一個JAVA辦法正常履行終了,JVM回從挪用棧中彈處該辦法的棧構造,然後持續處置前一個辦法.假如java辦法在履行代碼的進程中拋出異常,JVM必需找到能捕捉異常的catch塊代碼.它起首檢查以後辦法能否存在如許的catch代碼塊,假如存在就履行該 catch代碼塊,不然JVM回挪用棧中彈處該辦法的棧構造,持續到前一個辦法中查找適合的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) { 
   //假如不是未初始化狀況則拋出異常 
   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; 
   //分離從兩個數組的前面做輪回,假如相等則一向輪回,直到不等或數組到頭 
   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(); 
   //創立新的異常軌跡數組,並填充它 
    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(); 
  } 
} 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved