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();
}
}