Package java. Lang;
Import java. Io .*;
/**
*
* Throwable is the parent class of all errors and exceptiong.
* Note that there are four constructors:
* Throwable ()
* Throwable (string message)
* Throwable (throwable cause)
* Throwable (string message, throwable cause)
*
* Comment by liqiang
*
*/
Public class throwable implements serializable {
Private Static final long serialversionuid =-3034786055658047285l;
/**
* Native code saves some indication of the stack backtrace in this slot.
*/
Private transient object backtrace;
/**
*
* Information describing this exception
*
*/
Private string detailmessage;
/**
*
* Indicates the throwable that causes the current exception.
* If it is null, this exception is not caused by another throwable.
* If this object is the same as itself, it indicates that the cause object of this exception has not been initialized.
*
*/
Private throwable cause = this;
/**
*
* Array describing abnormal tracks
*
*/
Private stacktraceelement [] stacktrace;
/**
*
* Constructor. Because the object is not initialized, you can use initcause for initialization later.
* Fillinstacktrace can be used to initialize an array of its abnormal tracks
*
*/
Public throwable (){
Fillinstacktrace ();
}
/**
*
* Constructor
*
*/
Public throwable (string message ){
// Fill in the abnormal track Array
Fillinstacktrace ();
// Initialization exception description
Detailmessage = message;
}
/**
*
* Constructor. Cause indicates the source object.
*
*/
Public throwable (string message, throwable cause ){
Fillinstacktrace ();
Detailmessage = message;
This. Cause = cause;
}
/**
*
* Constructor
*
*/
Public throwable (throwable cause ){
Fillinstacktrace ();
Detailmessage = (cause = NULL? Null: cause. tostring ());
This. Cause = cause;
}
/**
*
* Obtain detailed information
*
*/
Public String getmessage (){
Return detailmessage;
}
/**
*
* Obtain detailed information
*
*/
Public String getlocalizedmessage (){
Return getmessage ();
}
/**
*
* Obtain the cause object.
*
*/
Public throwable getcause (){
Return (cause = This? Null: Cause );
}
/**
*
* Initialize the origin object. This method can only be called once without initialization.
*
*/
Public synchronized throwable initcause (throwable cause ){
// If it is not in the uninitialized status, an exception is thrown.
If (this. cause! = This)
Throw new illegalstateexception ("can't overwrite cause ");
// If the source object to be set is equal to itself, an exception is thrown.
If (cause = This)
Throw new illegalargumentexception ("self-causation not permitted ");
// Set the cause object
This. Cause = cause;
// Return the object of the cause
Return this;
}
/**
*
* String representation
*
*/
Public String tostring (){
String S = getclass (). getname ();
String message = getlocalizedmessage ();
Return (message! = NULL )? (S + ":" + message): S;
}
/**
*
* Print the error track
*
*/
Public void printstacktrace (){
Printstacktrace (system. Err );
}
/**
*
* Print the error track
*
*/
Public void printstacktrace (printstream s ){
Synchronized (s ){
// Call the tostring method of the current object
S. println (this );
// Obtain the exception track Array
Stacktraceelement [] Trace = getourstacktrace ();
// Print the string representation of each element
For (INT I = 0; I <trace. length; I ++)
S. println ("/tat" + trace [I]);
// Obtain the cause object
Throwable ourcause = getcause ();
// Print the information of the source object recursively
If (ourcause! = NULL)
Ourcause. printstacktraceascause (S, trace );
}
}
/**
*
* Print the information of the cause object.
*
* @ Param S: printed stream
* @ Param causedtrace has the exception track caused by this object
*
*/
Private void printstacktraceascause (printstream s,
Stacktraceelement [] causedtrace)
{
// Obtain the current exception track
Stacktraceelement [] Trace = getourstacktrace ();
// M is the last element position of the current abnormal track array,
// N is the last element of the exception track array caused by the current object
Int M = trace. Length-1, n = causedtrace. Length-1;
// Perform a loop from the back of the two arrays respectively. If the two arrays are equal, the loop continues until they are unequal or the array reaches the header.
While (M> = 0 & n> = 0 & trace [M]. Equals (causedtrace [N]) {
M --; n --;
}
// Same number
Int framesincommon = trace. Length-1-m;
// Print different error paths
S. println ("caused by:" + this );
For (INT I = 0; I <= m; I ++)
S. println ("/tat" + trace [I]);
// If the number is the same, the same number is printed.
If (framesincommon! = 0)
S. println ("/t..." + framesincommon + "more ");
// Obtain the cause object of this object and print the information recursively
Throwable ourcause = getcause ();
If (ourcause! = NULL)
Ourcause. printstacktraceascause (S, trace );
}
/**
*
* Print the error track
*
*/
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 the information of 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 );
}
/**
*
* Fill in abnormal tracks
*
*/
Public synchronized native throwable fillinstacktrace ();
/**
*
* Returns a copy of the current abnormal track.
*
*/
Public stacktraceelement [] getstacktrace (){
Return (stacktraceelement []) getourstacktrace (). Clone ();
}
/**
* Obtain the current exception track
*/
Private synchronized stacktraceelement [] getourstacktrace (){
// If this rule is called for the first time to initialize the exception track Array
If (stacktrace = NULL ){
// Obtain the depth of the exception track
Int depth = getstacktracedepth ();
// Create a new exception track array and fill it in
Stacktrace = new stacktraceelement [depth];
For (INT I = 0; I <depth; I ++)
Stacktrace [I] = getstacktraceelement (I); // obtain the exception track of the target
}
Return stacktrace;
}
/**
*
* Set the exception track
*
*/
Public void setstacktrace (stacktraceelement [] stacktrace ){
// Copy Parameters
Stacktraceelement [] defensivecopy =
(Stacktraceelement []) stacktrace. Clone ();
// If the parameter is set to an empty element, an exception is thrown.
For (INT I = 0; I <defensivecopy. length; I ++)
If (defensivecopy [I] = NULL)
Throw new nullpointerexception ("stacktrace [" + I + "]");
// Set the exception track of the current object
This. stacktrace = defensivecopy;
}
/**
*
* The depth of the exception track. 0 indicates that it cannot be obtained.
*
*/
Private native int getstacktracedepth ();
/**
*
* Obtain the abnormal track of the target
*
*/
Private native stacktraceelement getstacktraceelement (INT index );
Private synchronized void writeobject (Java. Io. objectoutputstream S)
Throws ioexception
{
Getourstacktrace ();
S. defaultwriteobject ();
}
}