Java异常学习一:Throwable源码

一.java异常类结构

常用的CheckedException

常用的RuntimeException

 

二.Throwable类源码

  1.  StackTraceElement。一个final类,代表栈轨迹中的元素,一个异常可能有多个元素。
    public final class StackTraceElement implements java.io.Serializable {
        // Normally initialized by VM (public constructor added in 1.5)
        private String declaringClass;//com.jyz.study.jdk.exception.ExceptionTest
        private String methodName;//equals
        private String fileName;//ExceptionTest.java
        private int    lineNumber;//17
    
        //可以看到 native方法lineNumber=-2
        public boolean isNativeMethod() {
            return lineNumber == -2;
        }
    
        //com.jyz.study.jdk.exception.ExceptionTest.equals(ExceptionTest.java:17)
        public String toString() {
            return getClassName() + "." + methodName +
                (isNativeMethod() ? "(Native Method)" :
                 (fileName != null && lineNumber >= 0 ?
                  "(" + fileName + ":" + lineNumber + ")" :
                  (fileName != null ?  "("+fileName+")" : "(Unknown Source)")));
        }
    
    
    
    }
     
  2. Throwable。java里所有错误和异常的基类。
    public class Throwable implements Serializable {
       //异常详细信息
        private String detailMessage;
        //初始化异常原因case为本身
        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();
        }
    
        //if cause == null return null
        public Throwable getCause() {
            return (cause==this ? null : cause);
        }
        //构造异常链
       public synchronized Throwable initCause(Throwable cause) {
            if (this.cause != this)//一旦通过初始化或者initCause设置了cause,就不能再次设置了
                throw new IllegalStateException("Can't overwrite cause");
            if (cause == this)//如果 cause 是此 throwable。(throwable 不能是它自己的 cause。)
                throw new IllegalArgumentException("Self-causation not permitted");
            this.cause = cause;
            return this;
        }
    
        
        public void printStackTrace() {
            printStackTrace(System.err);
        }
    
        //先打印thia,再打印方法调用的栈轨迹,最后打印cause
        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);
            }
        }
    
        //迭代打印cause
        private void printStackTraceAsCause(PrintStream 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);
        }
        public void printStackTrace(PrintWriter s) {
                //...同上
        }
        private void printStackTraceAsCause(PrintWriter s,
                                            StackTraceElement[] causedTrace)
        {
            //...同上}
    
        public StackTraceElement[] getStackTrace() {
            return (StackTraceElement[]) getOurStackTrace().clone();
        }
    
         //native方法获取方法调用的栈轨迹  一个Throwable的stackTrace是固定的
        private synchronized StackTraceElement[] getOurStackTrace() {
            // Initialize stack trace if this is the first call to this method
            if (stackTrace == null) {
                int depth = getStackTraceDepth();
                stackTrace = new StackTraceElement[depth];
                for (int i=0; i < depth; i++)
                    stackTrace[i] = getStackTraceElement(i);
            }
            return stackTrace;
        }
    
        native int getStackTraceDepth();
    
        native StackTraceElement getStackTraceElement(int index);
    
    
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值