• 异常处理类-Throwable源码详解


    package java.lang;
    import java.io.*;
    /**
     *
     * Throwable是所有Error和Exceptiong的父类 
     * 注意它有四个构造函数: 
     * Throwable() 
     * Throwable(String message) 
     * Throwable(Throwable cause) 
     * Throwable(String message, Throwable cause) 
     *
     */
    public class Throwable implements Serializable {
        private static final long serialVersionUID = -3042686055658047285L;
    
        /**
         * Native code saves some indication of the stack backtrace in this slot. 
         */
        private transient Object backtrace;
    
        /**
         * 描述此异常的信息 
         */
        private String detailMessage;
    
        /**
         * 表示当前异常由那个Throwable引起 
         * 如果为null表示此异常不是由其他Throwable引起的 
         * 如果此对象与自己相同,表明此异常的起因对象还没有被初始化 
         */
        private Throwable cause = this;
    
        /**
         * 描述异常轨迹的数组 
         */
        private StackTraceElement[] stackTrace;
    
        /**
         * 构造函数,起因对象没有被初始化可以在以后使用initCause进行初始化 
         * fillInStackTrace可以用来初始化它的异常轨迹的数组 
         */
        public Throwable() {
            fillInStackTrace();
        }
    
        /**
         * 构造函数 
         */
        public Throwable(String message) {
            //填充异常轨迹数组  
            fillInStackTrace();
            //初始化异常描述信息  
            detailMessage = message;
        }
    
        /**
         * 构造函数,cause表示起因对象 
         */
        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);
        }
    
        /**
         * 初始化起因对象,这个方法只能在未被初始化的情况下调用一次 
         */
        public synchronized Throwable initCause(Throwable cause) {
            //如果不是未初始化状态则抛出异常  
            if (this.cause != this)
                throw new IllegalStateException("Can't overwrite cause");
    
            //要设置的起因对象与自身相等则抛出异常  
            if (cause == this)
                throw new IllegalArgumentException("Self-causation not permitted");
    
            //设置起因对象  
            this.cause = cause;
            //返回设置的起因的对象  
            return this;
        }
    
        /**
         * 字符串表示形式 
         */
        public String toString() {
            String s = getClass().getName();
            String message = getLocalizedMessage();
            return (message != null) ? (s + ": " + message) : s;
        }
    
        /**
         * 打印出错误轨迹 
         */
        public void printStackTrace() {
            printStackTrace(System.err);
        }
    
        /**
         * 打印出错误轨迹 
         */
        public void printStackTrace(PrintStream s) {
            synchronized (s) {
                //调用当前对象的toString方法  
                s.println(this);
                //获取异常轨迹数组  
                StackTraceElement[] trace = getOurStackTrace();
    
                //打印出每个元素的字符串表示  
                for (int i=0; i < trace.length; i++)
                    s.println("	at " + trace[i]);
    
                //获取起因对象  
                Throwable ourCause = getCause();
    
                //递归的打印出起因对象的信息  
                if (ourCause != null)
                    ourCause.printStackTraceAsCause(s, trace);
            }
        }
    
        /**
         * 打印起因对象的信息 
         * @param s 打印的流 
         * @param causedTrace 有此对象引起的异常的异常轨迹  
         */
        private void printStackTraceAsCause(PrintStream s,
                                            StackTraceElement[] causedTrace)
        {
            //获得当前的异常轨迹  
            StackTraceElement[] trace = getOurStackTrace();
            //m为当前异常轨迹数组的最后一个元素位置,   
            //n为当前对象引起的异常的异常轨迹数组的最后一个元素  
            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("	at " + trace[i]);
            //如果有相同的则打印出相同的个数  
            if (framesInCommon != 0)
                s.println("	... " + framesInCommon + " more");
    
            //获得此对象的起因对象,并递归打印出信息  
            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("	at " + 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("	at " + trace[i]);
            if (framesInCommon != 0)
                s.println("	... " + framesInCommon + " more");
    
            // Recurse if we have a cause  
            Throwable ourCause = getCause();
            if (ourCause != null)
                ourCause.printStackTraceAsCause(s, trace);
        }
    
        /**
         * 填充异常轨迹 
         */
        public synchronized native Throwable fillInStackTrace();
    
        /**
         * 返回当前的异常轨迹的拷贝 
         */
        public StackTraceElement[] getStackTrace() {
            return (StackTraceElement[]) getOurStackTrace().clone();
        }
    
    
        /**
         * 获取当前的异常轨迹 
         */
        private synchronized StackTraceElement[] getOurStackTrace() {
            //如果第一次调用此方法则初始化异常轨迹数组  
            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;
        }
    
        /**
         * 异常轨迹的深度,0表示无法获得 
         */
        private native int getStackTraceDepth();
    
        /**
         * 获取指定位标的异常轨迹 
         */
        private native StackTraceElement getStackTraceElement(int index);
    
    
        private synchronized void writeObject(java.io.ObjectOutputStream s)
                throws IOException
        {
            getOurStackTrace();
            s.defaultWriteObject();
        }
    }
    
  • 相关阅读:
    蓝桥杯真题(1)
    蓝桥杯------历届真题
    第三届蓝桥杯 c/c++真题
    数据库三大范式个人理解,书上讲的太抽象
    c#线程池ThreadPool实例详解
    c#多线程thread实例详解
    C#中异步使用及回调
    c# 多线程的几种方式
    C#中委托的同步和异步有什么区别
    C#设计模式——单例模式的实现
  • 原文地址:https://www.cnblogs.com/MessiXiaoMo3334/p/11508461.html
Copyright © 2020-2023  润新知