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 异常处理 Throwable Error 和Exception

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

Java异常机制Throwable

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

Java.lang.throwable源代码解析

Java.lang.throwable源代码解析  自己留存 学习 package java.lang; import java.io.*; /** * * Throwable是所有Err...
  • docuxu
  • docuxu
  • 2017年10月14日 18:38
  • 102

common-logging源码解析

OK,现在我们来研究下common-logging的源码。这篇博客有参照上善若水的博客,感谢他的无私分享。 先来随便扯点吧,貌似所有这些流行的Logging框架都和Log4J多少有点关系(不太确定Co...
  • u011794238
  • u011794238
  • 2016年02月26日 14:56
  • 936

如何理解java.lang.Throwable

首先,我们看jdk对Throwable类的介绍:java.lang.Throwable类是java中的所有错误和异常的超类,只有这个类或者这个类的子类才能够被jvm或者java的throw或throw...
  • qj19842011
  • qj19842011
  • 2015年02月26日 17:08
  • 3902

java中的最顶级的异常类Throwable

Throwable类是整个异常体系类的父级类,当然最终追根溯源到底的父类当然要归于Object类。Throwable类实现了Serializable接口,表示Throwable可以进行序列化,继承自O...
  • pangqiandou
  • pangqiandou
  • 2016年12月03日 23:24
  • 2242

Logger框架源码解析

在移动软件开发中,我们经常会用到很多框架,如网络框架retrofit,图片加载框架glide,数据库框架litepal,日志框架Logger等。这些框架对应用都很重要,日志框架也是其中重要的一部分。因...
  • Awenyini
  • Awenyini
  • 2017年11月30日 17:15
  • 92

Android源码解析之(六)-->Log日志

首先说点题外话,对于想学android framework源码的同学,其实可以在github中fork一份,具体地址:https://github.com/android/platform_frame...
  • qq_23547831
  • qq_23547831
  • 2016年03月23日 14:53
  • 4226

JAVA编程——Throwable常见异常及源码详解

Throwable
  • RamProg
  • RamProg
  • 2015年08月16日 00:14
  • 977

JAVA编程——Throwable常见异常及源码详解

Throwable
  • RamProg
  • RamProg
  • 2015年08月16日 00:14
  • 977
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java源码分析(7)-Throwable
举报原因:
原因补充:

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