java源码分析(7)-Throwable

原创 2016年06月01日 17:28:57


Throwable

1.Throwable类

Throwable类实现了Serializable 接口,此类可用于序列化

public class Throwable implements Serializable {
    private transient Object backtrace;
    private String detailMessage;//用于存放异常的详细信息
    private Throwable cause = this;//初始化异常原因为本身
    private StackTraceElement[] stackTrace;//栈中的轨迹
    //四个构造函数
    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;
    }
    public String getMessage() {
        return detailMessage;
    }
    public String getLocalizedMessage() {
        return getMessage();
    }
    public Throwable getCause() {
        return (cause==this ? null : cause);//若cause为本身,即初始化时没有赋值,返回null,若已赋值,则返回值
    }

2.initCause

初始化cause,一个Throwable类只能设置一次cause

public synchronized Throwable initCause(Throwable cause) {
        if (this.cause != this)//已设置过cause,则抛异常,意思为只能设置一次
cause属性
            throw new IllegalStateException("Can't overwrite cause");
        if (cause == this)//若参数cause等于本身,抛异常
            throw new IllegalArgumentException("Self-causation not permitted");
        this.cause = cause;
        return this;
    }

3.打印错误信息

//遍历出错的原因轨迹
    public void printStackTrace(PrintStream 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);
        }
    }
    private void printStackTraceAsCause(PrintStream s,
                                        StackTraceElement[] causedTrace)
    {
        StackTraceElement[] trace = getOurStackTrace();//获得当前的异常轨迹数组
        int m = trace.length-1, n = causedTrace.length-1;
        //m为当前异常轨迹数组的最后一个元素的下标
        //n为当前对象引起的异常的异常轨迹数组的最后一个元素的下标
        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);
    }
    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);
        }
    }
    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);
    }

4.fillInStackTrace

 public synchronized native Throwable fillInStackTrace();//native方法获得方

法执行的栈轨迹

5.余下的一些功能

 public StackTraceElement[] getStackTrace() {
        return (StackTraceElement[]) getOurStackTrace().clone();
    }
    private synchronized StackTraceElement[] getOurStackTrace() {
        //只有第一次调用才会执行if模块中的代码
        if (stackTrace == null) {
            int depth = getStackTraceDepth();
            stackTrace = new StackTraceElement[depth];
            for (int i=0; i < depth; i++)
                stackTrace[i] = getStackTraceElement(i);
        }
        return stackTrace;
    }
    //设置异常的轨迹
    public void setStackTrace(StackTraceElement[] stackTrace) {
        StackTraceElement[] defensiveCopy =
            (StackTraceElement[]) stackTrace.clone();
        for (int i = 0; i < defensiveCopy.length; i++)
            if (defensiveCopy[i] == null)
                throw new NullPointerException("stackTrace[" + i + "]");

        this.stackTrace = defensiveCopy;
    }
    native int getStackTraceDepth();
    native StackTraceElement getStackTraceElement(int index);//获得特定下标的异

常轨迹
    //序列化对象
    private synchronized void writeObject(java.io.ObjectOutputStream s)
        throws IOException
    {
        getOurStackTrace();
        s.defaultWriteObject();
    }





版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

深入理解java异常处理机制

1. 引子        try…catch…finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解。不过,我亲自体验的“教训”告诉我,这个东西可不是想象中...
  • hguisu
  • hguisu
  • 2011-01-20 18:44
  • 264156

详解Java异常Throwable、Error、Exception、RuntimeException的区别

详解Java异常Throwable、Error、Exception、RuntimeException的区别---在Java中,根据错误性质将运行错误分为两类:错误和异常。

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

FindBugs规则整理

FindBugs是基于Bug Patterns概念,查找javabytecode(.class文件)中的潜在bug,主要检查bytecode中的bug patterns,如NullPoint空指针检查...

深入java.lang.Throwable

深入java.lang.Throwable java语言中,错误类的基类是java.lang.Error,异常类的基类是java.lang.Exception。 相同点:java.lang.Er...

获得java.lang.Throwable错误堆栈信息

在java语言中java.lang.Throwable是所有error、exceptiond

java 异常处理 Throwable Error 和Exception

Java异常类层次结构图:异常的英文单词是exception,字面翻译就是“意外、例外”的意思,也就是非正常情况。事实上,异常本质上是程序上的错误,包括程序逻辑错误和系统错误。比如使用空的引用、数组下...

浅谈java中的Throwable类

Throwable类 toString() 输出该异常的类名。 getMessage() 输出异常的信息,需要通过构造方法传入异常信息(例如病态信息)。 printStackTrace() 打印栈信息...

Java异常机制Throwable

Java中异常的概念以及处理异常 在Java程序运行期间出现了一个错误,这个错误可能是由于文件包含了错误信息,或者是由于网络连接出现问题,也可以是因为使用了无效的数组下标,或者是试图使用一个没有被赋值...

数据结构之堆

堆的定义 堆是一棵完全被填满的二叉树,可以的例外是在底层,底层上的元素从左到右填入。这样的树被称为完全二叉树。下面是一棵完全二叉树的结构图:                       &#...

java源码分析(7)-Throwable

 Throwable 1.Throwable类 Throwable类实现了Serializable 接口,此类可用于序列化 public class Throwable implement...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)