Source Home >> Java Source 1.6.0 >> java.lang.Throwable V 0.09
  • 001/*
  • 002 * @(#)Throwable.java 1.56 06/03/07
  • 003 *
  • 004 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
  • 005 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  • 006 */
  • 007
  • 008package java.lang;
  • 009import java.io.*;
  • 010
  • 011/**
  • 012 * The <code>Throwable</code> class is the superclass of all errors and
  • 013 * exceptions in the Java language. Only objects that are instances of this
  • 014 * class (or one of its subclasses) are thrown by the Java Virtual Machine or
  • 015 * can be thrown by the Java <code>throw</code> statement. Similarly, only
  • 016 * this class or one of its subclasses can be the argument type in a
  • 017 * <code>catch</code> clause.
  • 018 *
  • 019 * <p>Instances of two subclasses, {@link java.lang.Error} and
  • 020 * {@link java.lang.Exception}, are conventionally used to indicate
  • 021 * that exceptional situations have occurred. Typically, these instances
  • 022 * are freshly created in the context of the exceptional situation so
  • 023 * as to include relevant information (such as stack trace data).
  • 024 *
  • 025 * <p>A throwable contains a snapshot of the execution stack of its thread at
  • 026 * the time it was created. It can also contain a message string that gives
  • 027 * more information about the error. Finally, it can contain a <i>cause</i>:
  • 028 * another throwable that caused this throwable to get thrown. The cause
  • 029 * facility is new in release 1.4. It is also known as the <i>chained
  • 030 * exception</i> facility, as the cause can, itself, have a cause, and so on,
  • 031 * leading to a "chain" of exceptions, each caused by another.
  • 032 *
  • 033 * <p>One reason that a throwable may have a cause is that the class that
  • 034 * throws it is built atop a lower layered abstraction, and an operation on
  • 035 * the upper layer fails due to a failure in the lower layer. It would be bad
  • 036 * design to let the throwable thrown by the lower layer propagate outward, as
  • 037 * it is generally unrelated to the abstraction provided by the upper layer.
  • 038 * Further, doing so would tie the API of the upper layer to the details of
  • 039 * its implementation, assuming the lower layer's exception was a checked
  • 040 * exception. Throwing a "wrapped exception" (i.e., an exception containing a
  • 041 * cause) allows the upper layer to communicate the details of the failure to
  • 042 * its caller without incurring either of these shortcomings. It preserves
  • 043 * the flexibility to change the implementation of the upper layer without
  • 044 * changing its API (in particular, the set of exceptions thrown by its
  • 045 * methods).
  • 046 *
  • 047 * <p>A second reason that a throwable may have a cause is that the method
  • 048 * that throws it must conform to a general-purpose interface that does not
  • 049 * permit the method to throw the cause directly. For example, suppose
  • 050 * a persistent collection conforms to the {@link java.util.Collection
  • 051 * Collection} interface, and that its persistence is implemented atop
  • 052 * <tt>java.io</tt>. Suppose the internals of the <tt>add</tt> method
  • 053 * can throw an {@link java.io.IOException IOException}. The implementation
  • 054 * can communicate the details of the <tt>IOException</tt> to its caller
  • 055 * while conforming to the <tt>Collection</tt> interface by wrapping the
  • 056 * <tt>IOException</tt> in an appropriate unchecked exception. (The
  • 057 * specification for the persistent collection should indicate that it is
  • 058 * capable of throwing such exceptions.)
  • 059 *
  • 060 * <p>A cause can be associated with a throwable in two ways: via a
  • 061 * constructor that takes the cause as an argument, or via the
  • 062 * {@link #initCause(Throwable)} method. New throwable classes that
  • 063 * wish to allow causes to be associated with them should provide constructors
  • 064 * that take a cause and delegate (perhaps indirectly) to one of the
  • 065 * <tt>Throwable</tt> constructors that takes a cause. For example:
  • 066 * <pre>
  • 067 * try {
  • 068 * lowLevelOp();
  • 069 * } catch (LowLevelException le) {
  • 070 * throw new HighLevelException(le); // Chaining-aware constructor
  • 071 * }
  • 072 * </pre>
  • 073 * Because the <tt>initCause</tt> method is public, it allows a cause to be
  • 074 * associated with any throwable, even a "legacy throwable" whose
  • 075 * implementation predates the addition of the exception chaining mechanism to
  • 076 * <tt>Throwable</tt>. For example:
  • 077 * <pre>
  • 078 * try {
  • 079 * lowLevelOp();
  • 080 * } catch (LowLevelException le) {
  • 081 * throw (HighLevelException)
  • 082 new HighLevelException().initCause(le); // Legacy constructor
  • 083 * }
  • 084 * </pre>
  • 085 *
  • 086 * <p>Prior to release 1.4, there were many throwables that had their own
  • 087 * non-standard exception chaining mechanisms (
  • 088 * {@link ExceptionInInitializerError}, {@link ClassNotFoundException},
  • 089 * {@link java.lang.reflect.UndeclaredThrowableException},
  • 090 * {@link java.lang.reflect.InvocationTargetException},
  • 091 * {@link java.io.WriteAbortedException},
  • 092 * {@link java.security.PrivilegedActionException},
  • 093 * {@link java.awt.print.PrinterIOException},
  • 094 * {@link java.rmi.RemoteException} and
  • 095 * {@link javax.naming.NamingException}).
  • 096 * All of these throwables have been retrofitted to
  • 097 * use the standard exception chaining mechanism, while continuing to
  • 098 * implement their "legacy" chaining mechanisms for compatibility.
  • 099 *
  • 100 * <p>Further, as of release 1.4, many general purpose <tt>Throwable</tt>
  • 101 * classes (for example {@link Exception}, {@link RuntimeException},
  • 102 * {@link Error}) have been retrofitted with constructors that take
  • 103 * a cause. This was not strictly necessary, due to the existence of the
  • 104 * <tt>initCause</tt> method, but it is more convenient and expressive to
  • 105 * delegate to a constructor that takes a cause.
  • 106 *
  • 107 * <p>By convention, class <code>Throwable</code> and its subclasses have two
  • 108 * constructors, one that takes no arguments and one that takes a
  • 109 * <code>String</code> argument that can be used to produce a detail message.
  • 110 * Further, those subclasses that might likely have a cause associated with
  • 111 * them should have two more constructors, one that takes a
  • 112 * <code>Throwable</code> (the cause), and one that takes a
  • 113 * <code>String</code> (the detail message) and a <code>Throwable</code> (the
  • 114 * cause).
  • 115 *
  • 116 * <p>Also introduced in release 1.4 is the {@link #getStackTrace()} method,
  • 117 * which allows programmatic access to the stack trace information that was
  • 118 * previously available only in text form, via the various forms of the
  • 119 * {@link #printStackTrace()} method. This information has been added to the
  • 120 * <i>serialized representation</i> of this class so <tt>getStackTrace</tt>
  • 121 * and <tt>printStackTrace</tt> will operate properly on a throwable that
  • 122 * was obtained by deserialization.
  • 123 *
  • 124 * @author unascribed
  • 125 * @author Josh Bloch (Added exception chaining and programmatic access to
  • 126 * stack trace in 1.4.)
  • 127 * @version 1.56, 03/07/06
  • 128 * @since JDK1.0
  • 129 */
  • 130public class Throwable implements Serializable {
  • 131 /** use serialVersionUID from JDK 1.0.2 for interoperability */
  • 132 private static final long serialVersionUID = -3042686055658047285L;
  • 133
  • 134 /**
  • 135 * Native code saves some indication of the stack backtrace in this slot.
  • 136 */
  • 137 private transient Object backtrace;
  • 138
  • 139 /**
  • 140 * Specific details about the Throwable. For example, for
  • 141 * <tt>FileNotFoundException</tt>, this contains the name of
  • 142 * the file that could not be found.
  • 143 *
  • 144 * @serial
  • 145 */
  • 146 private String detailMessage;
  • 147
  • 148 /**
  • 149 * The throwable that caused this throwable to get thrown, or null if this
  • 150 * throwable was not caused by another throwable, or if the causative
  • 151 * throwable is unknown. If this field is equal to this throwable itself,
  • 152 * it indicates that the cause of this throwable has not yet been
  • 153 * initialized.
  • 154 *
  • 155 * @serial
  • 156 * @since 1.4
  • 157 */
  • 158 private Throwable cause = this;
  • 159
  • 160 /**
  • 161 * The stack trace, as returned by {@link #getStackTrace()}.
  • 162 *
  • 163 * @serial
  • 164 * @since 1.4
  • 165 */
  • 166 private StackTraceElement[] stackTrace;
  • 167 /*
  • 168 * This field is lazily initialized on first use or serialization and
  • 169 * nulled out when fillInStackTrace is called.
  • 170 */
  • 171
  • 172 /**
  • 173 * Constructs a new throwable with <code>null</code> as its detail message.
  • 174 * The cause is not initialized, and may subsequently be initialized by a
  • 175 * call to {@link #initCause}.
  • 176 *
  • 177 * <p>The {@link #fillInStackTrace()} method is called to initialize
  • 178 * the stack trace data in the newly created throwable.
  • 179 */
  • 180 public Throwable() {
  • 181 fillInStackTrace();
  • 182 }
  • 183
  • 184 /**
  • 185 * Constructs a new throwable with the specified detail message. The
  • 186 * cause is not initialized, and may subsequently be initialized by
  • 187 * a call to {@link #initCause}.
  • 188 *
  • 189 * <p>The {@link #fillInStackTrace()} method is called to initialize
  • 190 * the stack trace data in the newly created throwable.
  • 191 *
  • 192 * @param message the detail message. The detail message is saved for
  • 193 * later retrieval by the {@link #getMessage()} method.
  • 194 */
  • 195 public Throwable(String message) {
  • 196 fillInStackTrace();
  • 197 detailMessage = message;
  • 198 }
  • 199
  • 200 /**
  • 201 * Constructs a new throwable with the specified detail message and
  • 202 * cause. <p>Note that the detail message associated with
  • 203 * <code>cause</code> is <i>not</i> automatically incorporated in
  • 204 * this throwable's detail message.
  • 205 *
  • 206 * <p>The {@link #fillInStackTrace()} method is called to initialize
  • 207 * the stack trace data in the newly created throwable.
  • 208 *
  • 209 * @param message the detail message (which is saved for later retrieval
  • 210 * by the {@link #getMessage()} method).
  • 211 * @param cause the cause (which is saved for later retrieval by the
  • 212 * {@link #getCause()} method). (A <tt>null</tt> value is
  • 213 * permitted, and indicates that the cause is nonexistent or
  • 214 * unknown.)
  • 215 * @since 1.4
  • 216 */
  • 217 public Throwable(String message, Throwable cause) {
  • 218 fillInStackTrace();
  • 219 detailMessage = message;
  • 220 this.cause = cause;
  • 221 }
  • 222
  • 223 /**
  • 224 * Constructs a new throwable with the specified cause and a detail
  • 225 * message of <tt>(cause==null ? null : cause.toString())</tt> (which
  • 226 * typically contains the class and detail message of <tt>cause</tt>).
  • 227 * This constructor is useful for throwables that are little more than
  • 228 * wrappers for other throwables (for example, {@link
  • 229 * java.security.PrivilegedActionException}).
  • 230 *
  • 231 * <p>The {@link #fillInStackTrace()} method is called to initialize
  • 232 * the stack trace data in the newly created throwable.
  • 233 *
  • 234 * @param cause the cause (which is saved for later retrieval by the
  • 235 * {@link #getCause()} method). (A <tt>null</tt> value is
  • 236 * permitted, and indicates that the cause is nonexistent or
  • 237 * unknown.)
  • 238 * @since 1.4
  • 239 */
  • 240 public Throwable(Throwable cause) {
  • 241 fillInStackTrace();
  • 242 detailMessage = (cause==null ? null : cause.toString());
  • 243 this.cause = cause;
  • 244 }
  • 245
  • 246 /**
  • 247 * Returns the detail message string of this throwable.
  • 248 *
  • 249 * @return the detail message string of this <tt>Throwable</tt> instance
  • 250 * (which may be <tt>null</tt>).
  • 251 */
  • 252 public String getMessage() {
  • 253 return detailMessage;
  • 254 }
  • 255
  • 256 /**
  • 257 * Creates a localized description of this throwable.
  • 258 * Subclasses may override this method in order to produce a
  • 259 * locale-specific message. For subclasses that do not override this
  • 260 * method, the default implementation returns the same result as
  • 261 * <code>getMessage()</code>.
  • 262 *
  • 263 * @return The localized description of this throwable.
  • 264 * @since JDK1.1
  • 265 */
  • 266 public String getLocalizedMessage() {
  • 267 return getMessage();
  • 268 }
  • 269
  • 270 /**
  • 271 * Returns the cause of this throwable or <code>null</code> if the
  • 272 * cause is nonexistent or unknown. (The cause is the throwable that
  • 273 * caused this throwable to get thrown.)
  • 274 *
  • 275 * <p>This implementation returns the cause that was supplied via one of
  • 276 * the constructors requiring a <tt>Throwable</tt>, or that was set after
  • 277 * creation with the {@link #initCause(Throwable)} method. While it is
  • 278 * typically unnecessary to override this method, a subclass can override
  • 279 * it to return a cause set by some other means. This is appropriate for
  • 280 * a "legacy chained throwable" that predates the addition of chained
  • 281 * exceptions to <tt>Throwable</tt>. Note that it is <i>not</i>
  • 282 * necessary to override any of the <tt>PrintStackTrace</tt> methods,
  • 283 * all of which invoke the <tt>getCause</tt> method to determine the
  • 284 * cause of a throwable.
  • 285 *
  • 286 * @return the cause of this throwable or <code>null</code> if the
  • 287 * cause is nonexistent or unknown.
  • 288 * @since 1.4
  • 289 */
  • 290 public Throwable getCause() {
  • 291 return (cause==this ? null : cause);
  • 292 }
  • 293
  • 294 /**
  • 295 * Initializes the <i>cause</i> of this throwable to the specified value.
  • 296 * (The cause is the throwable that caused this throwable to get thrown.)
  • 297 *
  • 298 * <p>This method can be called at most once. It is generally called from
  • 299 * within the constructor, or immediately after creating the
  • 300 * throwable. If this throwable was created
  • 301 * with {@link #Throwable(Throwable)} or
  • 302 * {@link #Throwable(String,Throwable)}, this method cannot be called
  • 303 * even once.
  • 304 *
  • 305 * @param cause the cause (which is saved for later retrieval by the
  • 306 * {@link #getCause()} method). (A <tt>null</tt> value is
  • 307 * permitted, and indicates that the cause is nonexistent or
  • 308 * unknown.)
  • 309 * @return a reference to this <code>Throwable</code> instance.
  • 310 * @throws IllegalArgumentException if <code>cause</code> is this
  • 311 * throwable. (A throwable cannot be its own cause.)
  • 312 * @throws IllegalStateException if this throwable was
  • 313 * created with {@link #Throwable(Throwable)} or
  • 314 * {@link #Throwable(String,Throwable)}, or this method has already
  • 315 * been called on this throwable.
  • 316 * @since 1.4
  • 317 */
  • 318 public synchronized Throwable initCause(Throwable cause) {
  • 319 if (this.cause != this)
  • 320 throw new IllegalStateException("Can't overwrite cause");
  • 321 if (cause == this)
  • 322 throw new IllegalArgumentException("Self-causation not permitted");
  • 323 this.cause = cause;
  • 324 return this;
  • 325 }
  • 326
  • 327 /**
  • 328 * Returns a short description of this throwable.
  • 329 * The result is the concatenation of:
  • 330 * <ul>
  • 331 * <li> the {@linkplain Class#getName() name} of the class of this object
  • 332 * <li> ": " (a colon and a space)
  • 333 * <li> the result of invoking this object's {@link #getLocalizedMessage}
  • 334 * method
  • 335 * </ul>
  • 336 * If <tt>getLocalizedMessage</tt> returns <tt>null</tt>, then just
  • 337 * the class name is returned.
  • 338 *
  • 339 * @return a string representation of this throwable.
  • 340 */
  • 341 public String toString() {
  • 342 String s = getClass().getName();
  • 343 String message = getLocalizedMessage();
  • 344 return (message != null) ? (s + ": " + message) : s;
  • 345 }
  • 346
  • 347 /**
  • 348 * Prints this throwable and its backtrace to the
  • 349 * standard error stream. This method prints a stack trace for this
  • 350 * <code>Throwable</code> object on the error output stream that is
  • 351 * the value of the field <code>System.err</code>. The first line of
  • 352 * output contains the result of the {@link #toString()} method for
  • 353 * this object. Remaining lines represent data previously recorded by
  • 354 * the method {@link #fillInStackTrace()}. The format of this
  • 355 * information depends on the implementation, but the following
  • 356 * example may be regarded as typical:
  • 357 * <blockquote><pre>
  • 358 * java.lang.NullPointerException
  • 359 * at MyClass.mash(MyClass.java:9)
  • 360 * at MyClass.crunch(MyClass.java:6)
  • 361 * at MyClass.main(MyClass.java:3)
  • 362 * </pre></blockquote>
  • 363 * This example was produced by running the program:
  • 364 * <pre>
  • 365 * class MyClass {
  • 366 * public static void main(String[] args) {
  • 367 * crunch(null);
  • 368 * }
  • 369 * static void crunch(int[] a) {
  • 370 * mash(a);
  • 371 * }
  • 372 * static void mash(int[] b) {
  • 373 * System.out.println(b[0]);
  • 374 * }
  • 375 * }
  • 376 * </pre>
  • 377 * The backtrace for a throwable with an initialized, non-null cause
  • 378 * should generally include the backtrace for the cause. The format
  • 379 * of this information depends on the implementation, but the following
  • 380 * example may be regarded as typical:
  • 381 * <pre>
  • 382 * HighLevelException: MidLevelException: LowLevelException
  • 383 * at Junk.a(Junk.java:13)
  • 384 * at Junk.main(Junk.java:4)
  • 385 * Caused by: MidLevelException: LowLevelException
  • 386 * at Junk.c(Junk.java:23)
  • 387 * at Junk.b(Junk.java:17)
  • 388 * at Junk.a(Junk.java:11)
  • 389 * ... 1 more
  • 390 * Caused by: LowLevelException
  • 391 * at Junk.e(Junk.java:30)
  • 392 * at Junk.d(Junk.java:27)
  • 393 * at Junk.c(Junk.java:21)
  • 394 * ... 3 more
  • 395 * </pre>
  • 396 * Note the presence of lines containing the characters <tt>"..."</tt>.
  • 397 * These lines indicate that the remainder of the stack trace for this
  • 398 * exception matches the indicated number of frames from the bottom of the
  • 399 * stack trace of the exception that was caused by this exception (the
  • 400 * "enclosing" exception). This shorthand can greatly reduce the length
  • 401 * of the output in the common case where a wrapped exception is thrown
  • 402 * from same method as the "causative exception" is caught. The above
  • 403 * example was produced by running the program:
  • 404 * <pre>
  • 405 * public class Junk {
  • 406 * public static void main(String args[]) {
  • 407 * try {
  • 408 * a();
  • 409 * } catch(HighLevelException e) {
  • 410 * e.printStackTrace();
  • 411 * }
  • 412 * }
  • 413 * static void a() throws HighLevelException {
  • 414 * try {
  • 415 * b();
  • 416 * } catch(MidLevelException e) {
  • 417 * throw new HighLevelException(e);
  • 418 * }
  • 419 * }
  • 420 * static void b() throws MidLevelException {
  • 421 * c();
  • 422 * }
  • 423 * static void c() throws MidLevelException {
  • 424 * try {
  • 425 * d();
  • 426 * } catch(LowLevelException e) {
  • 427 * throw new MidLevelException(e);
  • 428 * }
  • 429 * }
  • 430 * static void d() throws LowLevelException {
  • 431 * e();
  • 432 * }
  • 433 * static void e() throws LowLevelException {
  • 434 * throw new LowLevelException();
  • 435 * }
  • 436 * }
  • 437 *
  • 438 * class HighLevelException extends Exception {
  • 439 * HighLevelException(Throwable cause) { super(cause); }
  • 440 * }
  • 441 *
  • 442 * class MidLevelException extends Exception {
  • 443 * MidLevelException(Throwable cause) { super(cause); }
  • 444 * }
  • 445 *
  • 446 * class LowLevelException extends Exception {
  • 447 * }
  • 448 * </pre>
  • 449 */
  • 450 public void printStackTrace() {
  • 451 printStackTrace(System.err);
  • 452 }
  • 453
  • 454 /**
  • 455 * Prints this throwable and its backtrace to the specified print stream.
  • 456 *
  • 457 * @param s <code>PrintStream</code> to use for output
  • 458 */
  • 459 public void printStackTrace(PrintStream s) {
  • 460 synchronized (s) {
  • 461 s.println(this);
  • 462 StackTraceElement[] trace = getOurStackTrace();
  • 463 for (int i=0; i < trace.length; i++)
  • 464 s.println("\tat " + trace[i]);
  • 465
  • 466 Throwable ourCause = getCause();
  • 467 if (ourCause != null)
  • 468 ourCause.printStackTraceAsCause(s, trace);
  • 469 }
  • 470 }
  • 471
  • 472 /**
  • 473 * Print our stack trace as a cause for the specified stack trace.
  • 474 */
  • 475 private void printStackTraceAsCause(PrintStream s,
  • 476 StackTraceElement[] causedTrace)
  • 477 {
  • 478 // assert Thread.holdsLock(s);
  • 479
  • 480 // Compute number of frames in common between this and caused
  • 481 StackTraceElement[] trace = getOurStackTrace();
  • 482 int m = trace.length-1, n = causedTrace.length-1;
  • 483 while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {
  • 484 m--; n--;
  • 485 }
  • 486 int framesInCommon = trace.length - 1 - m;
  • 487
  • 488 s.println("Caused by: " + this);
  • 489 for (int i=0; i <= m; i++)
  • 490 s.println("\tat " + trace[i]);
  • 491 if (framesInCommon != 0)
  • 492 s.println("\t... " + framesInCommon + " more");
  • 493
  • 494 // Recurse if we have a cause
  • 495 Throwable ourCause = getCause();
  • 496 if (ourCause != null)
  • 497 ourCause.printStackTraceAsCause(s, trace);
  • 498 }
  • 499
  • 500 /**
  • 501 * Prints this throwable and its backtrace to the specified
  • 502 * print writer.
  • 503 *
  • 504 * @param s <code>PrintWriter</code> to use for output
  • 505 * @since JDK1.1
  • 506 */
  • 507 public void printStackTrace(PrintWriter s) {
  • 508 synchronized (s) {
  • 509 s.println(this);
  • 510 StackTraceElement[] trace = getOurStackTrace();
  • 511 for (int i=0; i < trace.length; i++)
  • 512 s.println("\tat " + trace[i]);
  • 513
  • 514 Throwable ourCause = getCause();
  • 515 if (ourCause != null)
  • 516 ourCause.printStackTraceAsCause(s, trace);
  • 517 }
  • 518 }
  • 519
  • 520 /**
  • 521 * Print our stack trace as a cause for the specified stack trace.
  • 522 */
  • 523 private void printStackTraceAsCause(PrintWriter s,
  • 524 StackTraceElement[] causedTrace)
  • 525 {
  • 526 // assert Thread.holdsLock(s);
  • 527
  • 528 // Compute number of frames in common between this and caused
  • 529 StackTraceElement[] trace = getOurStackTrace();
  • 530 int m = trace.length-1, n = causedTrace.length-1;
  • 531 while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {
  • 532 m--; n--;
  • 533 }
  • 534 int framesInCommon = trace.length - 1 - m;
  • 535
  • 536 s.println("Caused by: " + this);
  • 537 for (int i=0; i <= m; i++)
  • 538 s.println("\tat " + trace[i]);
  • 539 if (framesInCommon != 0)
  • 540 s.println("\t... " + framesInCommon + " more");
  • 541
  • 542 // Recurse if we have a cause
  • 543 Throwable ourCause = getCause();
  • 544 if (ourCause != null)
  • 545 ourCause.printStackTraceAsCause(s, trace);
  • 546 }
  • 547
  • 548 /**
  • 549 * Fills in the execution stack trace. This method records within this
  • 550 * <code>Throwable</code> object information about the current state of
  • 551 * the stack frames for the current thread.
  • 552 *
  • 553 * @return a reference to this <code>Throwable</code> instance.
  • 554 * @see java.lang.Throwable#printStackTrace()
  • 555 */
  • 556 public synchronized native Throwable fillInStackTrace();
  • 557
  • 558 /**
  • 559 * Provides programmatic access to the stack trace information printed by
  • 560 * {@link #printStackTrace()}. Returns an array of stack trace elements,
  • 561 * each representing one stack frame. The zeroth element of the array
  • 562 * (assuming the array's length is non-zero) represents the top of the
  • 563 * stack, which is the last method invocation in the sequence. Typically,
  • 564 * this is the point at which this throwable was created and thrown.
  • 565 * The last element of the array (assuming the array's length is non-zero)
  • 566 * represents the bottom of the stack, which is the first method invocation
  • 567 * in the sequence.
  • 568 *
  • 569 * <p>Some virtual machines may, under some circumstances, omit one
  • 570 * or more stack frames from the stack trace. In the extreme case,
  • 571 * a virtual machine that has no stack trace information concerning
  • 572 * this throwable is permitted to return a zero-length array from this
  • 573 * method. Generally speaking, the array returned by this method will
  • 574 * contain one element for every frame that would be printed by
  • 575 * <tt>printStackTrace</tt>.
  • 576 *
  • 577 * @return an array of stack trace elements representing the stack trace
  • 578 * pertaining to this throwable.
  • 579 * @since 1.4
  • 580 */
  • 581 public StackTraceElement[] getStackTrace() {
  • 582 return (StackTraceElement[]) getOurStackTrace().clone();
  • 583 }
  • 584
  • 585 private synchronized StackTraceElement[] getOurStackTrace() {
  • 586 // Initialize stack trace if this is the first call to this method
  • 587 if (stackTrace == null) {
  • 588 int depth = getStackTraceDepth();
  • 589 stackTrace = new StackTraceElement[depth];
  • 590 for (int i=0; i < depth; i++)
  • 591 stackTrace[i] = getStackTraceElement(i);
  • 592 }
  • 593 return stackTrace;
  • 594 }
  • 595
  • 596 /**
  • 597 * Sets the stack trace elements that will be returned by
  • 598 * {@link #getStackTrace()} and printed by {@link #printStackTrace()}
  • 599 * and related methods.
  • 600 *
  • 601 * This method, which is designed for use by RPC frameworks and other
  • 602 * advanced systems, allows the client to override the default
  • 603 * stack trace that is either generated by {@link #fillInStackTrace()}
  • 604 * when a throwable is constructed or deserialized when a throwable is
  • 605 * read from a serialization stream.
  • 606 *
  • 607 * @param stackTrace the stack trace elements to be associated with
  • 608 * this <code>Throwable</code>. The specified array is copied by this
  • 609 * call; changes in the specified array after the method invocation
  • 610 * returns will have no affect on this <code>Throwable</code>'s stack
  • 611 * trace.
  • 612 *
  • 613 * @throws NullPointerException if <code>stackTrace</code> is
  • 614 * <code>null</code>, or if any of the elements of
  • 615 * <code>stackTrace</code> are <code>null</code>
  • 616 *
  • 617 * @since 1.4
  • 618 */
  • 619 public void setStackTrace(StackTraceElement[] stackTrace) {
  • 620 StackTraceElement[] defensiveCopy =
  • 621 (StackTraceElement[]) stackTrace.clone();
  • 622 for (int i = 0; i < defensiveCopy.length; i++)
  • 623 if (defensiveCopy[i] == null)
  • 624 throw new NullPointerException("stackTrace[" + i + "]");
  • 625
  • 626 this.stackTrace = defensiveCopy;
  • 627 }
  • 628
  • 629 /**
  • 630 * Returns the number of elements in the stack trace (or 0 if the stack
  • 631 * trace is unavailable).
  • 632 */
  • 633 private native int getStackTraceDepth();
  • 634
  • 635 /**
  • 636 * Returns the specified element of the stack trace.
  • 637 *
  • 638 * @param index index of the element to return.
  • 639 * @throws IndexOutOfBoundsException if <tt>index < 0 ||
  • 640 * index >= getStackTraceDepth() </tt>
  • 641 */
  • 642 private native StackTraceElement getStackTraceElement(int index);
  • 643
  • 644 private synchronized void writeObject(java.io.ObjectOutputStream s)
  • 645 throws IOException
  • 646 {
  • 647 getOurStackTrace(); // Ensure that stackTrace field is initialized.
  • 648 s.defaultWriteObject();
  • 649 }
  • 650}

文件:Throwable.java
包名:java.lang
类名:Throwable
继承:
接口:[Serializable]