源码解析之Throwable

本文深入解析了Java中的Throwable类,它是所有异常和错误的基础类。文章介绍了Throwable类的主要用途、构造方法及成员变量,并探讨了StackTraceElement如何记录异常发生时的方法调用栈。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


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及其回溯打印到标准错误流。

package com.hexiang.utils; import java.awt.Component; import javax.swing.JOptionPane; /** * This class ExceptionManager and its subclasses are a form of * Exception. It is used to wrap all the Throwable instances * and handle them in a unified way. It will show the information which consists of * StackTraces and Messages by using JOptionPanel. * * @author Estelle * @version 1.0 * @see java.lang.Exception * @since jdk 1.5 */ public class ExceptionManager extends RuntimeException { private static final long serialVersionUID = -6963187366089365790L; /** * This field alerter is used to show the information the Class offered. * * @see javax.swing.JOptionPane */ private JOptionPane alerter; /** * This static method create an instance of the ExceptionManager by invoking the * constructor ExceptionManager(String msg). * * @param msg The message will pass the specified constructor * @return An instance of the ExceptionManager created by invoking the constructor * ExceptionManager(String msg). */ public static ExceptionManager wrap(String msg){ return new ExceptionManager(msg); } /** * This static method create an instance of the ExceptionManager by invoking the * constructor ExceptionManager(Throwable throwable). * * @param throwable The cause will pass the specified constructor * @return An instance of the ExceptionManager created by invoking the constructor * ExceptionManager(Throwable throwable). */ public static ExceptionManager wrap(Throwable throwable){ return new ExceptionManager(throwable); } /** * This static method create an instance of the ExceptionManager by invoking the * constructor ExceptionManager(String msg,Throwable throwable). * * @param msg The message will pass the specified constructor * @param throwable The cause will pass the specified c
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值