📄 throwable.java
字号:
* { * a(); * } * catch(HighLevelException e) * { * e.printStackTrace(); * } * } * static void a() throws HighLevelException * { * try * { * b(); * } * catch(MidLevelException e) * { * throw new HighLevelException(e); * } * } * static void b() throws MidLevelException * { * c(); * } * static void c() throws MidLevelException * { * try * { * d(); * } * catch(LowLevelException e) * { * throw new MidLevelException(e); * } * } * static void d() throws LowLevelException * { * e(); * } * static void e() throws LowLevelException * { * throw new LowLevelException(); * } * } * class HighLevelException extends Exception * { * HighLevelException(Throwable cause) { super(cause); } * } * class MidLevelException extends Exception * { * MidLevelException(Throwable cause) { super(cause); } * } * class LowLevelException extends Exception * { * } * </pre> * <p> * <pre> * HighLevelException: MidLevelException: LowLevelException * at Junk.a(Junk.java:13) * at Junk.main(Junk.java:4) * Caused by: MidLevelException: LowLevelException * at Junk.c(Junk.java:23) * at Junk.b(Junk.java:17) * at Junk.a(Junk.java:11) * ... 1 more * Caused by: LowLevelException * at Junk.e(Junk.java:30) * at Junk.d(Junk.java:27) * at Junk.c(Junk.java:21) * ... 3 more * </pre> */ public void printStackTrace() { printStackTrace(System.err); } /** * Print a stack trace to the specified PrintStream. See * {@link #printStackTrace()} for the sample format. * * @param s the PrintStream to write the trace to */ public void printStackTrace(PrintStream s) { s.print(stackTraceString()); } /** * Prints the exception, the detailed message and the stack trace * associated with this Throwable to the given <code>PrintWriter</code>. * The actual output written is implemention specific. Use the result of * <code>getStackTrace()</code> when more precise information is needed. * * <p>This implementation first prints a line with the result of this * object's <code>toString()</code> method. * <br> * Then for all elements given by <code>getStackTrace</code> it prints * a line containing three spaces, the string "at " and the result of calling * the <code>toString()</code> method on the <code>StackTraceElement</code> * object. If <code>getStackTrace()</code> returns an empty array it prints * a line containing three spaces and the string * "<<No stacktrace available>>". * <br> * Then if <code>getCause()</code> doesn't return null it adds a line * starting with "Caused by: " and the result of calling * <code>toString()</code> on the cause. * <br> * Then for every cause (of a cause, etc) the stacktrace is printed the * same as for the top level <code>Throwable</code> except that as soon * as all the remaining stack frames of the cause are the same as the * the last stack frames of the throwable that the cause is wrapped in * then a line starting with three spaces and the string "... X more" is * printed, where X is the number of remaining stackframes. * * @param w the PrintWriter to write the trace to * @since 1.1 */ public void printStackTrace (PrintWriter pw) { pw.print(stackTraceString()); } private static final String nl = System.getProperty("line.separator"); // Create whole stack trace in a stringbuffer so we don't have to print // it line by line. This prevents printing multiple stack traces from // different threads to get mixed up when written to the same PrintWriter. private String stackTraceString() { StringBuffer sb = new StringBuffer(); // Main stacktrace StackTraceElement[] stack = getStackTrace(); stackTraceStringBuffer(sb, this.toString(), stack, 0); // The cause(s) Throwable cause = getCause(); while (cause != null) { // Cause start first line sb.append("Caused by: "); // Cause stacktrace StackTraceElement[] parentStack = stack; stack = cause.getStackTrace(); if (parentStack == null || parentStack.length == 0) stackTraceStringBuffer(sb, cause.toString(), stack, 0); else { int equal = 0; // Count how many of the last stack frames are equal int frame = stack.length-1; int parentFrame = parentStack.length-1; while (frame > 0 && parentFrame > 0) { if (stack[frame].equals(parentStack[parentFrame])) { equal++; frame--; parentFrame--; } else break; } stackTraceStringBuffer(sb, cause.toString(), stack, equal); } cause = cause.getCause(); } return sb.toString(); } // Adds to the given StringBuffer a line containing the name and // all stacktrace elements minus the last equal ones. private static void stackTraceStringBuffer(StringBuffer sb, String name, StackTraceElement[] stack, int equal) { // (finish) first line sb.append(name); sb.append(nl); // The stacktrace if (stack == null || stack.length == 0) { sb.append(" <<No stacktrace available>>"); sb.append(nl); } else { for (int i = 0; i < stack.length-equal; i++) { sb.append(" at "); sb.append(stack[i] == null ? "<<Unknown>>" : stack[i].toString()); sb.append(nl); } if (equal > 0) { sb.append(" ..."); sb.append(equal); sb.append(" more"); sb.append(nl); } } } /** * Fill in the stack trace with the current execution stack. * * @return this same throwable * @see #printStackTrace() */ public Throwable fillInStackTrace() { vmState = VMThrowable.fillInStackTrace(this); stackTrace = null; // Should be regenerated when used. return this; } /** * Provides access to the information printed in {@link #printStackTrace()}. * The array is non-null, with no null entries, although the virtual * machine is allowed to skip stack frames. If the array is not 0-length, * then slot 0 holds the information on the stack frame where the Throwable * was created (or at least where <code>fillInStackTrace()</code> was * called). * * @return an array of stack trace information, as available from the VM * @since 1.4 */ public StackTraceElement[] getStackTrace() { if (stackTrace == null) if (vmState == null) stackTrace = new StackTraceElement[0]; else { stackTrace = vmState.getStackTrace(this); vmState = null; // No longer needed } return stackTrace; } /** * Change the stack trace manually. This method is designed for remote * procedure calls, which intend to alter the stack trace before or after * serialization according to the context of the remote call. * <p> * The contents of the given stacktrace is copied so changes to the * original array do not change the stack trace elements of this * throwable. * * @param stackTrace the new trace to use * @throws NullPointerException if stackTrace is null or has null elements * @since 1.4 */ public void setStackTrace(StackTraceElement[] stackTrace) { int i = stackTrace.length; StackTraceElement[] st = new StackTraceElement[i]; while (--i >= 0) { st[i] = stackTrace[i]; if (st[i] == null) throw new NullPointerException("Element " + i + " null"); } this.stackTrace = st; } /** * VM state when fillInStackTrace was called. * Used by getStackTrace() to get an array of StackTraceElements. * Cleared when no longer needed. */ private transient VMThrowable vmState;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -