源码解析之Throwable


Throwable 类是exceptions和error的父类。只有作为此类(或其某个子类)实例的对象才会由Java虚拟机抛出,或者可以由Java throw语句抛出。 同样,只有这个类或它的一个子类可以是catch子句中的参数类型。 由于java检查编译时异常的存在,Throwable和Throwable的任何子类(不是RuntimeException或Error的子类)均被视为检查异常。

通常用Throwable 的两个子类的实例Error和Exception来表示出现异常情况。 通常情况下,这些实例是在发生异常情况下才创建的,以此来包含异常的相关信息(如堆栈跟踪数据)。

一个throwable包含其创建时的线程执行堆栈的全部信息。 它也可以包含一个消息字符串,提供有关错误的更多信息。也包含了引起这个throwable发生的另一个throwable的,这是一个因果关系。所有发生在一次线程执行中的因果关系被称之为链式异常!

在Throwable类用StackTraceElement数组来表示保存在堆栈轨迹中的方法对象

StackTraceElement表示StackTrace(堆栈轨迹)中的一个方法对象,属性包括方法的类名、方法名、文件名以及调用的行数。

public final class StackTraceElement implements java.io.Serializable {
    // Normally initialized by VM (public constructor added in 1.5)
    private String declaringClass;
    private String methodName;
    private String fileName;
    private int    lineNumber;

    public StackTraceElement(String declaringClass, String methodName,
                             String fileName, int lineNumber) {
	//requireNonNull,如果对象为null,则抛出异常,打印参数列表中的String信息
        this.declaringClass = Objects.requireNonNull(declaringClass, "Declaring class is null");
        this.methodName     = Objects.requireNonNull(methodName, "Method name is null");
        this.fileName       = fileName;
        this.lineNumber     = lineNumber;
    }
 
    public String getFileName() {
        return fileName;
    }
    public int getLineNumber() {
        return lineNumber;
    }
    
    public String getClassName() {
        return declaringClass;
    }
    
    public String getMethodName() {
        return methodName;
    }
    
    public boolean isNativeMethod() {
        return lineNumber == -2;
    }
   
    public String toString() {
        return getClassName() + "." + methodName +
            (isNativeMethod() ? "(Native Method)" :
             (fileName != null && lineNumber >= 0 ?
              "(" + fileName + ":" + lineNumber + ")" :
              (fileName != null ?  "("+fileName+")" : "(Unknown Source)")));
    }
   
    public boolean equals(Object obj) {
        if (obj==this)
            return true;
        if (!(obj instanceof StackTraceElement))
            return false;
        StackTraceElement e = (StackTraceElement)obj;
        return e.declaringClass.equals(declaringClass) &&
            e.lineNumber == lineNumber &&
            Objects.equals(methodName, e.methodName) &&
            Objects.equals(fileName, e.fileName);
    }

    public int hashCode() {
        int result = 31*declaringClass.hashCode() + methodName.hashCode();
        result = 31*result + Objects.hashCode(fileName);
        result = 31*result + lineNumber;
        return result;
    }

    private static final long serialVersionUID = 6992337162326171013L;
}

Throwable类中,一些初始化的设定

//初始化一个cause为这个异常本身
private Throwable cause = this;
//初始化cause,这个cause不能是已经被设置过的也不能是该类自身
public synchronized Throwable initCause(Throwable cause) {
        if (this.cause != this)
            throw new IllegalStateException("Can't overwrite cause with " +
                                            Objects.toString(cause, "a null"), this);
        if (cause == this)
            throw new IllegalArgumentException("Self-causation not permitted", this);
        this.cause = cause;
        return this;
    }

//存放异常的详细信息
private String detailMessage;

//初始化栈中的轨迹为一个未分配的栈
private StackTraceElement[] stackTrace = UNASSIGNED_STACK;

//一些会随着异常一起被打印的信息
private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";

private static final String SELF_SUPPRESSION_MESSAGE = "Self-suppression not permitted";

private static final String CAUSE_CAPTION = "Caused by: ";

private static final String SUPPRESSED_CAPTION = "Suppressed: ";

构造器:

 //一个throwable实例被创建,对应的构造器去调用fillStackTrack()方法 ,往堆栈中打印异常信息!!  

public Throwable() {
        fillInStackTrace();
    }

    public Throwable(String message) {
        fillInStackTrace();
        detailMessage = message;
    }

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

    protected Throwable(String message, Throwable cause,
                        boolean enableSuppression,
                        boolean writableStackTrace) {
        if (writableStackTrace) {
            fillInStackTrace();
        } else {
            stackTrace = null;
        }
        detailMessage = message;
        this.cause = cause;
        if (!enableSuppression)
            suppressedExceptions = null;
    }

fillInstackTrack方法:

public synchronized Throwable fillInStackTrace() {
        if (stackTrace != null ||
            backtrace != null /* Out of protocol state */ ) {
            fillInStackTrace(0);
            stackTrace = UNASSIGNED_STACK;
        }
        return this;
    }
    
    private native Throwable fillInStackTrace(int dummy);
其他的就是一些诸如printStackTrace方法等等,作用是将此throwable及其回溯打印到标准错误流。

你可能感兴趣的:(源码解析)