Java中Throwable源码阅读

来源:互联网 发布:linux 挂载目录 编辑:程序博客网 时间:2024/05/22 10:48

Throwable 源码阅读笔记

读的不是很懂,但是大致明白自定义异常中的那几个常用的参数的发源地了,这是项目中自定义异常经常使用的几个参数和方法,在Throwable中都可以查到影子:

protected StringpositionName;
protected String labelName;
protected String message=""; 
public String getMessage() {
return message;
}

Throwable 源码

package com.cloud.exe;

import  java.io.*;

/**

 * Throwable

 * 异常,可抛出的异常类

 */

publicclass Throwableimplements Serializable {

    /**

     * Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,

     * JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较

     * 如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)

     */

    privatestaticfinallongserialVersionUID = -3042686055658047285L;

 

    /**

     * 关于异常的细节:比如文件找不到的异常,这个detailMessage可以记录为什么文件找不到

     */

    private StringdetailMessage;

 

    /**

     * 异常的实力:初始化的时候默认是本身

     */

    private Throwablecause =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;

    }

    /**

     * 自定义异常的时候,一般重写该方法,满足业务需要

     * @return

     */

    public String getMessage() {

        returndetailMessage;

    }

    /**

     * 一般不适用,多处理资源国际化问题

     * @return

     */

    public String getLocalizedMessage() {

        return getMessage();

    }

    /**

     * 如果cause=null,就扔回一个null

     * @return

     */

    public Throwable getCause() {

        return (cause==this ?null : cause);

    }

 

    /**

     * 初始化起因对象,这个方法只能在未被初始化的情况下调用一次 

     */

    publicsynchronized Throwable initCause(Throwable cause) {

      //如果不是未初始化状态则抛出异常

        if (this.cause !=this)

            thrownew IllegalStateException("Can't overwrite cause");

        //要设置的起因对象与自身相等则抛出异常

        if (cause ==this)

            thrownew IllegalArgumentException("Self-causation not permitted");

        //设置起因

        this.cause = cause;

        returnthis;

    }

    /**

     * 把异常信息转成字符串信息

     */

    public String toString() {

        String s = getClass().getName();

        String message = getLocalizedMessage();

        return (message !=null) ? (s +": " + message) : s;

    }

    /**

     * 打印异常轨迹

     */

    publicvoid printStackTrace() {

        printStackTrace(System.err);

    }

    /**

     * 打印异常轨迹

     * @param s

     */

    publicvoid 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);

        }

    }

    /**

     * P打印起因对象的信息 

     * @param s打印的流 

     * @param causedTrace有此对象引起的异常的异常轨迹

     */

    privatevoid printStackTraceAsCause(PrintStream s,

                                        StackTraceElement[] causedTrace)

    {

        //获取当前的异常信息

        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");

        Throwable ourCause = getCause();

        if (ourCause !=null)

            ourCause.printStackTraceAsCause(s, trace);

    }

 

    /**

     * 打印错误信息

     */

    publicvoid 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);

        }

    }

 

    /**

     * 打印异常起因对象信息

     */

    privatevoid printStackTraceAsCause(PrintWriter s,

                                        StackTraceElement[] causedTrace)

    {

        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");

        Throwable ourCause = getCause();

        if (ourCause !=null)

            ourCause.printStackTraceAsCause(s, trace);

    }

 

    /**

     * 异常轨迹填充

     */

    publicsynchronizednative Throwable fillInStackTrace();

    /**

     * 返回异常信息的拷贝信息

     */

    public StackTraceElement[] getStackTrace() {

        return (StackTraceElement[]) getOurStackTrace().clone();

    }

    /**

     * 获取当前异常的轨迹

     * @return

     */

    privatesynchronized StackTraceElement[] getOurStackTrace() {

        if (stackTrace ==null) {

            int depth = getStackTraceDepth();

            stackTrace = new StackTraceElement[depth];

            for (int i=0; i < depth; i++)

                stackTrace[i] = getStackTraceElement(i);

        }

        returnstackTrace;

    }

 

    /**

     * 设置异常轨迹

     */

    publicvoid setStackTrace(StackTraceElement[] stackTrace) {

        StackTraceElement[] defensiveCopy =

            (StackTraceElement[]) stackTrace.clone();

        for (int i = 0; i < defensiveCopy.length; i++)

            if (defensiveCopy[i] ==null)

                thrownew NullPointerException("stackTrace[" + i +"]");

 

        this.stackTrace = defensiveCopy;

    }

 

    /**

     * 异常轨迹的深度

     */

    nativeint getStackTraceDepth();

 

    /**

     * 获取指定位标的异常轨迹

     */

    native StackTraceElement getStackTraceElement(int index);

 

    privatesynchronizedvoid writeObject(java.io.ObjectOutputStream s)

        throws IOException

    {

        getOurStackTrace();

        s.defaultWriteObject();

    }

}

 


0 0
原创粉丝点击