`

java Throwable源码

 
阅读更多
  1. package java.lang;     
  2. import java.io.*;     
  3. /**   
  4. *    
  5. * Throwable是所有Error和Exceptiong的父类   
  6. * 注意它有四个构造函数:   
  7. * Throwable()   
  8. * Throwable(String message)   
  9. * Throwable(Throwable cause)   
  10. * Throwable(String message, Throwable cause)   
  11. *    
  12. */    
  13. public class Throwable implements Serializable {     
  14.       private static final long serialVersionUID = -3042686055658047285L;     
  15.     
  16.       /**   
  17.        * Native code saves some indication of the stack backtrace in this slot.   
  18.        */    
  19.       private transient Object backtrace;      
  20.     
  21.       /**   
  22.        * 描述此异常的信息   
  23.        */    
  24.       private String detailMessage;     
  25.     
  26.       /**   
  27.        * 表示当前异常由那个Throwable引起   
  28.         * 如果为null表示此异常不是由其他Throwable引起的   
  29.         * 如果此对象与自己相同,表明此异常的起因对象还没有被初始化   
  30.        */    
  31.       private Throwable cause = this;     
  32.     
  33.       /**   
  34.        * 描述异常轨迹的数组   
  35.        */    
  36.       private StackTraceElement[] stackTrace;     
  37.     
  38.       /**   
  39.        * 构造函数,起因对象没有被初始化可以在以后使用initCause进行初始化   
  40.         * fillInStackTrace可以用来初始化它的异常轨迹的数组   
  41.        */    
  42.       public Throwable() {     
  43.           fillInStackTrace();     
  44.       }     
  45.     
  46.       /**   
  47.        * 构造函数   
  48.        */    
  49.       public Throwable(String message) {     
  50.          //填充异常轨迹数组     
  51.           fillInStackTrace();     
  52.          //初始化异常描述信息     
  53.           detailMessage = message;     
  54.       }     
  55.     
  56.       /**   
  57.        * 构造函数,cause表示起因对象   
  58.        */    
  59.       public Throwable(String message, Throwable cause) {     
  60.           fillInStackTrace();     
  61.           detailMessage = message;     
  62.           this.cause = cause;     
  63.       }     
  64.     
  65.       /**   
  66.        * 构造函数   
  67.        */    
  68.       public Throwable(Throwable cause) {     
  69.           fillInStackTrace();     
  70.           detailMessage = (cause==null ? null : cause.toString());     
  71.           this.cause = cause;     
  72.       }     
  73.     
  74.       /**   
  75.        * 获取详细信息   
  76.        */    
  77.       public String getMessage() {     
  78.           return detailMessage;     
  79.       }     
  80.     
  81.       /**   
  82.        * 获取详细信息   
  83.        */    
  84.       public String getLocalizedMessage() {     
  85.           return getMessage();     
  86.       }     
  87.     
  88.       /**   
  89.        * 获取起因对象   
  90.        */    
  91.       public Throwable getCause() {     
  92.           return (cause==this ? null : cause);     
  93.       }     
  94.     
  95.       /**   
  96.        * 初始化起因对象,这个方法只能在未被初始化的情况下调用一次   
  97.        */    
  98.       public synchronized Throwable initCause(Throwable cause) {     
  99.          //如果不是未初始化状态则抛出异常     
  100.           if (this.cause != this)     
  101.               throw new IllegalStateException("Can't overwrite cause");     
  102.              
  103.          //要设置的起因对象与自身相等则抛出异常     
  104.           if (cause == this)     
  105.               throw new IllegalArgumentException("Self-causation not permitted");     
  106.              
  107.          //设置起因对象     
  108.           this.cause = cause;     
  109.          //返回设置的起因的对象     
  110.           return this;     
  111.       }     
  112.     
  113.       /**   
  114.        * 字符串表示形式   
  115.        */    
  116.       public String toString() {          
  117.           String s = getClass().getName();             
  118.           String message = getLocalizedMessage();           
  119.           return (message != null) ? (s + ": " + message) : s;     
  120.       }     
  121.     
  122.       /**   
  123.        * 打印出错误轨迹   
  124.        */    
  125.       public void printStackTrace() {      
  126.           printStackTrace(System.err);     
  127.       }     
  128.     
  129.       /**   
  130.        * 打印出错误轨迹   
  131.        */    
  132.       public void printStackTrace(PrintStream s) {     
  133.           synchronized (s) {     
  134.             //调用当前对象的toString方法     
  135.               s.println(this);     
  136.             //获取异常轨迹数组     
  137.               StackTraceElement[] trace = getOurStackTrace();     
  138.                  
  139.             //打印出每个元素的字符串表示     
  140.               for (int i=0; i < trace.length; i++)     
  141.                 s.println("\tat " + trace[i]);     
  142.     
  143.             //获取起因对象     
  144.               Throwable ourCause = getCause();     
  145.                  
  146.             //递归的打印出起因对象的信息     
  147.               if (ourCause != null)     
  148.                 ourCause.printStackTraceAsCause(s, trace);     
  149.           }     
  150.       }     
  151.     
  152.       /**   
  153.        * 打印起因对象的信息   
  154.        * @param s 打印的流   
  155.         * @param causedTrace 有此对象引起的异常的异常轨迹    
  156.        */    
  157.       private void printStackTraceAsCause(PrintStream s,     
  158.                                           StackTraceElement[] causedTrace)     
  159.       {     
  160.          //获得当前的异常轨迹     
  161.           StackTraceElement[] trace = getOurStackTrace();     
  162.          //m为当前异常轨迹数组的最后一个元素位置,      
  163.          //n为当前对象引起的异常的异常轨迹数组的最后一个元素     
  164.           int m = trace.length-1, n = causedTrace.length-1;     
  165.          //分别从两个数组的后面做循环,如果相等则一直循环,直到不等或数组到头     
  166.           while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {     
  167.               m--; n--;     
  168.          }     
  169.              
  170.          //相同的个数     
  171.           int framesInCommon = trace.length - 1 - m;     
  172.              
  173.          //打印出不同的错误轨迹     
  174.           s.println("Caused by: " + this);     
  175.           for (int i=0; i <= m; i++)     
  176.               s.println("\tat " + trace[i]);     
  177.           //如果有相同的则打印出相同的个数     
  178.           if (framesInCommon != 0)     
  179.               s.println("\t... " + framesInCommon + " more");     
  180.     
  181.          //获得此对象的起因对象,并递归打印出信息     
  182.           Throwable ourCause = getCause();     
  183.           if (ourCause != null)     
  184.               ourCause.printStackTraceAsCause(s, trace);     
  185.       }     
  186.     
  187.       /**   
  188.        * 打印出错误轨迹   
  189.        */    
  190.       public void printStackTrace(PrintWriter s) {      
  191.           synchronized (s) {     
  192.               s.println(this);     
  193.               StackTraceElement[] trace = getOurStackTrace();     
  194.               for (int i=0; i < trace.length; i++)     
  195.                   s.println("\tat " + trace[i]);     
  196.     
  197.               Throwable ourCause = getCause();     
  198.               if (ourCause != null)     
  199.                   ourCause.printStackTraceAsCause(s, trace);     
  200.           }     
  201.       }     
  202.     
  203.       /**   
  204.        * 打印起因对象的信息   
  205.         */    
  206.       private void printStackTraceAsCause(PrintWriter s,     
  207.                                           StackTraceElement[] causedTrace)     
  208.       {     
  209.           // assert Thread.holdsLock(s);     
  210.     
  211.           // Compute number of frames in common between this and caused     
  212.           StackTraceElement[] trace = getOurStackTrace();     
  213.           int m = trace.length-1, n = causedTrace.length-1;     
  214.           while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {     
  215.               m--; n--;     
  216.           }     
  217.           int framesInCommon = trace.length - 1 - m;     
  218.     
  219.           s.println("Caused by: " + this);     
  220.           for (int i=0; i <= m; i++)     
  221.               s.println("\tat " + trace[i]);     
  222.           if (framesInCommon != 0)     
  223.               s.println("\t... " + framesInCommon + " more");     
  224.     
  225.           // Recurse if we have a cause     
  226.           Throwable ourCause = getCause();     
  227.           if (ourCause != null)     
  228.               ourCause.printStackTraceAsCause(s, trace);     
  229.       }     
  230.     
  231.       /**   
  232.        * 填充异常轨迹   
  233.        */    
  234.       public synchronized native Throwable fillInStackTrace();     
  235.     
  236.       /**   
  237.        * 返回当前的异常轨迹的拷贝   
  238.        */    
  239.       public StackTraceElement[] getStackTrace() {     
  240.           return (StackTraceElement[]) getOurStackTrace().clone();     
  241.       }     
  242.     
  243.          
  244.       /**   
  245.        * 获取当前的异常轨迹   
  246.         */    
  247.       private synchronized StackTraceElement[] getOurStackTrace() {     
  248.          //如果第一次调用此方法则初始化异常轨迹数组     
  249.           if (stackTrace == null) {     
  250.             //获得异常轨迹深度     
  251.               int depth = getStackTraceDepth();     
  252.             //创建新的异常轨迹数组,并填充它     
  253.               stackTrace = new StackTraceElement[depth];     
  254.                  
  255.             for (int i=0; i < depth; i++)     
  256.                 stackTrace[i] = getStackTraceElement(i);//获取指定位标的异常轨迹     
  257.           }     
  258.              
  259.           return stackTrace;     
  260.       }     
  261.     
  262.       /**   
  263.        * 设置异常轨迹   
  264.        */    
  265.       public void setStackTrace(StackTraceElement[] stackTrace) {     
  266.          //拷贝设置参数     
  267.           StackTraceElement[] defensiveCopy =     
  268.               (StackTraceElement[]) stackTrace.clone();     
  269.              
  270.          //如果设置参数有空元素则抛出异常     
  271.           for (int i = 0; i < defensiveCopy.length; i++)     
  272.               if (defensiveCopy[i] == null)     
  273.                   throw new NullPointerException("stackTrace[" + i + "]");     
  274.     
  275.          //设置当前对象的异常轨迹     
  276.           this.stackTrace = defensiveCopy;     
  277.       }     
  278.     
  279.       /**   
  280.        * 异常轨迹的深度,0表示无法获得   
  281.        */    
  282.       private native int getStackTraceDepth();     
  283.     
  284.       /**   
  285.        * 获取指定位标的异常轨迹   
  286.        */    
  287.       private native StackTraceElement getStackTraceElement(int index);     
  288.     
  289.          
  290.       private synchronized void writeObject(java.io.ObjectOutputStream s)     
  291.           throws IOException     
  292.       {     
  293.           getOurStackTrace();     
  294.           s.defaultWriteObject();     
  295.       }     
  296. }    
分享到:
评论

相关推荐

    Java SE 源码 Java SE 源码

    5. **异常处理**:Java的异常处理机制在`java.lang.Throwable`及其子类中体现,通过源码可以理解异常的抛出、捕获和处理流程。 6. **反射机制**:`java.lang.reflect`包提供了运行时检查和操作类、接口、字段和方法...

    Mining_JAVA源码_源码.zip

    再次,JAVA源码中的异常处理和错误报告机制,如`java.lang.Throwable`及其子类,帮助我们更好地理解和处理程序运行时可能出现的问题。同时,JAVA的反射API (`java.lang.reflect`) 和注解处理器(`javax.annotation....

    疯狂Java讲义源码(第六部分)

    《疯狂Java讲义》是Java编程领域的一本经典教材,其源码分为多个部分,这里主要探讨的是第六部分,涵盖了第11至13章的内容。这三章涉及了Java高级特性和面向对象编程的深入理解,对于进阶Java开发者来说至关重要。...

    Java官方英文版源码

    - **异常处理**:`java.lang.Throwable`及其子类,如Exception和Error,理解异常的层次结构和处理机制。 - **多线程**:`java.lang.Thread`和`java.util.concurrent`包,探究并发编程的实现,如锁、同步、线程池等...

    Java spring AOP源码

    ### Java Spring AOP源码分析 #### 概述 在探讨Spring AOP源码之前,我们首先需要了解Spring AOP的基本概念以及它的工作原理。面向切面编程(Aspect-Oriented Programming, AOP)是一种编程范式,它通过将横切关注...

    java常用类库源码

    4. **异常处理**:Java.lang.Throwable及其子类如Exception和Error定义了异常处理机制。源码分析有助于理解异常的层次结构和如何有效地抛出、捕获和处理异常。 5. **反射API**:Java.lang.reflect允许程序在运行时...

    java源码之jdk源码

    - Java的异常处理机制基于`java.lang.Throwable`类及其子类,如Exception和Error。理解何时抛出异常,如何捕获和处理异常,是编写健壮代码的基础。 7. **垃圾收集(Garbage Collection)**: - 虽然JVM的垃圾收集...

    java深入源码级的面试题.pdf

    Java 深入源码级的面试题涵盖了多个核心领域,包括垃圾回收机制、字符编码、代理模式以及异常处理。让我们逐一深入探讨这些知识点。 首先,垃圾回收机制是 Java 语言的一大特性,它负责自动释放不再使用的内存。当...

    class_java_源码.rar.rar

    标题 "class_java_源码.rar.rar" 暗示了这是一个包含Java源代码的压缩文件,可能是某个Java项目或库的源代码集合。虽然没有具体的描述,我们可以根据Java类文件(.class)的一般用途来推测其中可能包含的知识点。 1...

    java源码 app崩溃后自动重启 示例源码

    "java源码 app崩溃后自动重启 示例源码"这个主题涉及到的是如何处理应用崩溃,并在崩溃后自动恢复运行,以提供良好的用户体验。这个场景通常通过实现自定义的错误处理机制来完成,以下是一些关键知识点: 1. **全局...

    SUN公司官网JAVA源代码

    异常类是Java.lang.Throwable的子类,常见的有IOException、NullPointerException、ArrayIndexOutOfBoundsException等。 7. **集合框架**:Java集合框架包括List、Set、Queue等接口以及ArrayList、HashSet、...

    java api_javaapi_

    3. **异常处理**:`java.lang.Throwable`是所有异常和错误的基类,包括`Exception`和`Error`。异常处理通过`try-catch-finally`块来捕获和处理运行时可能出现的问题,确保程序的健壮性。 4. **输入/输出流**:`java...

    Java SDK源代码

    4. **异常处理**:Java的异常处理机制基于`try-catch-finally`语句块,`java.lang.Throwable`是所有异常类的父类,包括`Exception`和`Error`。理解和掌握异常处理对于编写健壮的代码至关重要。 5. **I/O与NIO**:`...

    Java rt.jar 源码分析

    7. **异常处理**: `java.lang.Throwable`及其子类,如`Exception`和`Error`,构成了Java的异常处理系统。源码分析可以解释异常的构造、传播和捕获过程。 8. **工具类**: `java.util`和`java.text`等包中的工具类,...

    Java puzzlers(java 解惑)附源码

    书中可能包含一些关于异常链、try-catch-finally语句块和throwable类型的puzzlers,通过分析这些源码,我们可以学习如何优雅地处理异常,避免程序的脆弱性。 再者,集合框架是Java编程的基石,但其内部机制如果不...

    java rt包源代码

    3. **异常处理**:`java.lang.Throwable`是所有异常和错误的基类,包括`Exception`和`Error`。`Exception`用于表示程序运行时出现的非致命问题,而`Error`通常表示严重的问题,如系统资源耗尽。 4. **多线程**:`...

    jdk1.8 rt.jar 源码

    6. **异常处理**:`java.lang.Throwable`及其子类,如`Exception`和`Error`,定义了Java的异常模型。源码可以帮助理解异常的传播和处理机制。 7. **日期与时间API**:在JDK 1.8中,`java.time`包提供了新的日期和...

    JavaGuide.pdf

    答:Throwable 是 Java 中的异常类的父类。 Java 多线程 17. Java 中的多线程是什么? 答:Java 中的多线程是指同一个程序中多个线程的并发执行。 18. Java 中的线程的生命周期是什么? 答:Java 中的线程的生命...

    Java WebSocket编程,java实现websocket,Java源码.zip

    本压缩包文件包含了关于Java WebSocket编程的相关知识和源码示例。 首先,让我们了解一下WebSocket的基本概念。WebSocket协议是基于TCP的,它通过在HTTP的握手过程中升级连接来建立持久的全双工通道。这意味着...

Global site tag (gtag.js) - Google Analytics