Resolves the parent class java.lang.Throwable for all errors and exceptions in Java

  • 2020-05-07 19:37:40
  • OfStack

In the java language, the base class for the error class is java.lang.Error, and the base class for the exception class is java.lang.Exception.
1) similarities: java.lang.Error and java.lang.Exception are subclasses of java. And throw new MyException (); Among them, MyError class is a subclass of java.lang.Error, and MyException class is a subclass of java.lang.Exception.
2) differences: java.lang.Error itself and its subclasses do not need the support of try-catch statement, and can return the method at any time, as defined below:


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

The MyError class is a subclass of the java.lang.Error class.
java.lang.Exception itself and its subclasses require support from the try-catch statement. The following method definition is incorrect:


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

The correct method is defined as follows:


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

The MyException class is a subclass of java.lang.Exception.

JAVA exception is when java program running in the presence of abnormal situation created object, it encapsulates the abnormal information, java abnormal root class to java lang. Throwable, the entire class, there are two subclasses java directly. lang. Error and java lang. Exception. Error program itself is unable to restore serious mistakes. Exception says can be captured and deal with abnormal errors. A program JVM method using the call stack to track each thread in 1 series Method invocation process of column, the stack will save the local information of each call method. For independent JAVA procedures, can be 1 until the program's main method. When a new method called JVM to describe the method of stack structure in the stack, located at the top of the stack method for proper execution. When a JAVA method complete, normal JVM back from the call stack was shot in the method of stack structure, and then continue to process before a method. If java method throws an exception, in the process of executing code JVM must find can catch exceptions catch block of code. It first to see whether the current method exist such catch code block, if there is a will execute the catch code block, otherwise JVM call stack shot in the back stack structure of this method, a method to find the right before going on to catch code block. Finally if JVM to chase up the main () method, which is 1 straight gave main exception () method, still can't find the exception handling code block, the thread will abort, if this thread is the main thread, the application has been terminated, at this time JVM will throw the exception directly to the user and see the original exception information on the end of the user.

Java.lang.throwable source code analysis


package java.lang; 
import java.io.*; 
/** 
* 
* Throwable Is that all Error and Exceptiong The parent class  
*  Note that it has 4 constructors : 
* 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; 
 
  /** 
  *  Describes the information for this exception  
  */ 
  private String detailMessage; 
 
  /** 
  *  Represents the current exception by that Throwable cause  
  *  If it is null Indicates that this exception is not otherwise Throwable Caused by the  
  *  If the object is the same as itself , Indicates that the cause object for this exception has not been initialized  
  */ 
  private Throwable cause = this; 
 
  /** 
  *  An array that describes the trajectory of an exception  
  */ 
  private StackTraceElement[] stackTrace; 
 
  /** 
  *  The constructor , The cause object is not initialized and can be used later initCause initialize  
  * fillInStackTrace Can be used to initialize an array of its exception traces  
  */ 
  public Throwable() { 
   fillInStackTrace(); 
  } 
 
  /** 
  *  The constructor  
  */ 
  public Throwable(String message) { 
   // Fills the array of exception tracks  
   fillInStackTrace(); 
   // Initializes the exception description information  
   detailMessage = message; 
  } 
 
  /** 
  *  The constructor ,cause Represents the cause object  
  */ 
  public Throwable(String message, Throwable cause) { 
   fillInStackTrace(); 
   detailMessage = message; 
   this.cause = cause; 
  } 
 
  /** 
  *  The constructor  
  */ 
  public Throwable(Throwable cause) { 
   fillInStackTrace(); 
   detailMessage = (cause==null ? null : cause.toString()); 
   this.cause = cause; 
  } 
 
  /** 
  *  Get details  
  */ 
  public String getMessage() { 
   return detailMessage; 
  } 
 
  /** 
  *  Get details  
  */ 
  public String getLocalizedMessage() { 
   return getMessage(); 
  } 
 
  /** 
  *  Get the cause object  
  */ 
  public Throwable getCause() { 
   return (cause==this ? null : cause); 
  } 
 
  /** 
  *  Initializes the cause object , This method can only be called if it is not initialized 1 time  
  */ 
  public synchronized Throwable initCause(Throwable cause) { 
   // An exception is thrown if the state is not uninitialized  
   if (this.cause != this) 
    throw new IllegalStateException("Can't overwrite cause"); 
   
   // The cause object to be set to be equal to itself throws an exception  
   if (cause == this) 
    throw new IllegalArgumentException("Self-causation not permitted"); 
   
   // Set the cause object  
   this.cause = cause; 
   // Object that returns the cause of the setting  
   return this; 
  } 
 
  /** 
  *  String representation  
  */ 
  public String toString() {  
   String s = getClass().getName();   
   String message = getLocalizedMessage();  
   return (message != null) ? (s + ": " + message) : s; 
  } 
 
  /** 
  *  Print out the error trace  
  */ 
  public void printStackTrace() { 
   printStackTrace(System.err); 
  } 
 
  /** 
  *  Print out the error trace  
  */ 
  public void printStackTrace(PrintStream s) { 
   synchronized (s) { 
   // Invokes the current object toString methods  
    s.println(this); 
   // Gets an array of exception traces  
    StackTraceElement[] trace = getOurStackTrace(); 
    
   // Prints out a string representation of each element  
    for (int i=0; i < trace.length; i++) 
    s.println("\tat " + trace[i]); 
 
   // Get the cause object  
    Throwable ourCause = getCause(); 
    
   // Recursively prints out information about the cause object  
    if (ourCause != null) 
    ourCause.printStackTraceAsCause(s, trace); 
   } 
  } 
 
  /** 
  *  Print information about the cause object  
  * @param s  Print the flow  
  * @param causedTrace  The exception trace with the exception caused by this object  
  */ 
  private void printStackTraceAsCause(PrintStream s, 
           StackTraceElement[] causedTrace) 
  { 
   // Get the current exception trajectory  
   StackTraceElement[] trace = getOurStackTrace(); 
   //m Is the end of the current array of exception traces 1 Element position , 
   //n Is the end of the exception trace array for the exception caused by the current object 1 An element  
   int m = trace.length-1, n = causedTrace.length-1; 
   // Loop through the end of each array , If they are equal 1 Straight cycle , To the end of inequality or array  
   while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) { 
    m--; n--; 
   } 
   
   // Same number  
   int framesInCommon = trace.length - 1 - m; 
   
   // Print out different error tracks  
   s.println("Caused by: " + this); 
   for (int i=0; i <= m; i++) 
    s.println("\tat " + trace[i]); 
   // If you have the same number you print out the same number  
   if (framesInCommon != 0) 
    s.println("\t... " + framesInCommon + " more"); 
 
   // Gets the cause object for this object , And recursively print out the information  
   Throwable ourCause = getCause(); 
   if (ourCause != null) 
    ourCause.printStackTraceAsCause(s, trace); 
  } 
 
  /** 
  *  Print out the error 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); 
   } 
  } 
 
  /** 
  *  Print information about the cause object  
  */ 
  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); 
  } 
 
  /** 
  *  Filled anomaly trajectory  
  */ 
  public synchronized native Throwable fillInStackTrace(); 
 
  /** 
  *  Returns a copy of the current exception trace  
  */ 
  public StackTraceElement[] getStackTrace() { 
   return (StackTraceElement[]) getOurStackTrace().clone(); 
  } 
 
  
  /** 
  *  Gets the current exception trajectory  
  */ 
  private synchronized StackTraceElement[] getOurStackTrace() { 
   // If the first 1 The second call to this method initializes the array of exception traces  
   if (stackTrace == null) { 
   // Obtain the depth of the anomalous trajectory  
    int depth = getStackTraceDepth(); 
   // Creates a new array of exception traces , And fill it  
    stackTrace = new StackTraceElement[depth]; 
    
   for (int i=0; i < depth; i++) 
    stackTrace[i] = getStackTraceElement(i);// Gets the abnormal trace of the specified position  
   } 
   
   return stackTrace; 
  } 
 
  /** 
  *  Set abnormal trajectory  
  */ 
  public void setStackTrace(StackTraceElement[] stackTrace) { 
   // Copy setting parameters  
   StackTraceElement[] defensiveCopy = 
    (StackTraceElement[]) stackTrace.clone(); 
   
   // An exception is thrown if an empty element is set as an argument  
   for (int i = 0; i < defensiveCopy.length; i++) 
    if (defensiveCopy[i] == null) 
     throw new NullPointerException("stackTrace[" + i + "]"); 
 
   // Sets the exception path for the current object  
   this.stackTrace = defensiveCopy; 
  } 
 
  /** 
  *  The depth of the anomalous trajectory ,0 Is not available  
  */ 
  private native int getStackTraceDepth(); 
 
  /** 
  *  Gets the abnormal trace of the specified position  
  */ 
  private native StackTraceElement getStackTraceElement(int index); 
 
  
  private synchronized void writeObject(java.io.ObjectOutputStream s) 
   throws IOException 
  { 
   getOurStackTrace(); 
   s.defaultWriteObject(); 
  } 
} 


Related articles: