- 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("\tat " + 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("\tat " + trace[i]);
- //如果有相同的则打印出相同的个数
- if (framesInCommon != 0)
- s.println("\t... " + 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("\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);
- }
- /**
- * 填充异常轨迹
- */
- 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();
- }
- }
- 转载于http://riddickbryant.iteye.com/blog/444185
Java.lang.throwable源代码
最新推荐文章于 2023-12-28 16:37:25 发布