• 沒有找到結果。

The Throwable Class Hierarchy

在文檔中 Beginning Java 7Get coding with (頁 159-162)

Java provides a hierarchy of classes that represent different kinds of exceptions. These classes are rooted in java.lang.Throwable, the ultimate superclass for all throwables (exception and error objects—

exceptions and errors, for short—that can be thrown). Table 3-1 identifies and describes most of Throwable’s constructors and methods.

Table 3-1. Throwable’s Constructors and Methods

Method Description

Throwable() Create a throwable with a null detail message

and cause.

Throwable(String message) Create a throwable with the specified detail message and a null cause.

Throwable(String message, Throwable cause)

Create a throwable with the specified detail message and cause.

protected Throwable(String message, Throwable cause, boolean

enableSuppression, boolean writableStackTrace)

Create a throwable with the specified detail message, cause, suppression enabled or disabled, and writable stack trace enabled or disabled.

CHAPTER 3  EXPLORING ADVANCED LANGUAGE FEATURES

Throwable(Throwable cause) Create a throwable whose detail message is the string representation of a nonnull cause, or null.

void addSuppressed(Throwable exception)

Append the specified exception to the exceptions that were suppressed in order to deliver this exception.

Throwable fillInStackTrace() Fill in the execution stack trace. This method records information about the current state of the stack frames for the current thread within this throwable. (I discuss threads in Chapter 4.) Throwable getCause() Return the cause of this throwable. If there is no

cause, null is returned.

String getMessage() Return this throwable’s detail message, which might be null.

StackTraceElement[] getStackTrace() Provide programmatic access to the stack trace information printed by printStackTrace() as an array of stack trace elements, each representing one stack frame.

Throwable[] getSuppressed() Return an array containing all exceptions that were suppressed (typically by the try-with-resources statement, discussed later) in order to deliver this exception.

Throwable initCause(Throwable cause) Initialize the cause of this throwable to the specified value.

void printStackTrace() Print this throwable and its backtrace of stack frames to the standard error stream.

void setStackTrace(StackTraceElement[]

stackTrace)

Set the stack trace elements that will be returned by getStackTrace() and printed by

printStackTrace() and related methods.

It is not uncommon for a class’s public methods to call helper methods that throw various exceptions. A public method will probably not document exceptions thrown from a helper method because they are implementation details that often should not be visible to the public method’s caller.

However, because this exception might be helpful in diagnosing the problem, the public method can wrap the lower-level exception in a higher-level exception that is documented in the public

method’s contract interface. The wrapped exception is known as a cause because its existence causes the higher-level exception to be thrown. A cause is created by invoking the Throwable(Throwable cause) or Throwable(String message, Throwable cause) constructor, which invoke the initCause() method to

CHAPTER 3  EXPLORING ADVANCED LANGUAGE FEATURES

store the cause. If you do not call either constructor, you can alternatively call initCause() directly, but must do so immediately after creating the throwable. Call the getCause() method to return the cause.

When one exception causes another exception, the first exception is usually caught and then the second exception is thrown in response. In other words, there is a causal connection between the two exceptions. In contrast, there are situations where two independent exceptions can be thrown in sibling code blocks; for example, in the try block of a try-with-resources statement (discussed later in this chapter) and the compiler-generated finally block that closes the resource. In these situations, only one of the thrown exceptions can be propagated.

In the try-with-resources statement, when there are two such exceptions, the exception originating from the try block is propagated and the exception from the finally block is added (via the

addSuppressed() method) to the list of exceptions suppressed by the exception from the try block. As an exception unwinds the stack, it can accumulate multiple suppressed exceptions. An array of the suppressed expressions can be retrieved by calling getSuppressed().

When an exception is thrown, it leaves behind a stack of unfinished method calls. Throwable’s constructors call fillInStackTrace() to record this stack trace information, which is output by calling printStackTrace().

The getStackTrace() method provides programmatic access to the stack trace by returning this information as an array of java.lang.StackTraceElement instances – each instance represents one stack entry. StackTraceElement provides methods to return stack trace information. For example, String getMethodName() returns the name of an unfinished method.

The setStackTrace() method is designed for use by Remote Procedure Call (RPC) frameworks (RPC is briefly discussed in Chapter 11) and other advanced systems, allowing the client to override the default stack trace that is generated by fillInStackTrace() when a throwable is constructed, or deserialized when a throwable is read from a serialization stream. (I will discuss serialization in Chapter 8.)

Except for Throwable(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace), each Throwable constructor always treats suppression as being enabled, and always calls fillInStackTrace(). In contrast, this constructor lets you disable suppression by passing false to enableSuppression, and prevent fillInStackTrace() from being called by passing false to writableStackTrace. Pass false to writableStackTrace when you plan to override the default stack trace and want to avoid the unnecessary fillInStackTrace() method calls. Similarly, pass false to

enableSuppression when repeatedly catching and rethrowing the same exception object (to implement control flow between two subsystems, for example) or in other exceptional circumstances.

You will notice that Throwable(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) is signified as a protected constructor. Also, its Java documentation includes the following sentence: “Subclasses of Throwable should document any conditions under which suppression is disabled and document conditions under which the stack trace is not writable.” This is an example of “design and document for class extension,” which I discuss in Chapter 2.

Moving down the throwable hierarchy, you encounter the java.lang.Exception and

java.lang.Error classes, which respectively represent exceptions and errors. Each class offers five constructors that pass their arguments to their Throwable counterparts, but provides no methods apart from those that are inherited from Throwable.

Exception is itself subclassed by java.lang.CloneNotSupportedException (discussed in Chapter 2), java.io.IOException (discussed in Chapter 8), and other classes. Similarly, Error is itself subclassed by java.lang.AssertionError (discussed later in this chapter), java.lang.OutOfMemoryError, and other classes.

CHAPTER 3  EXPLORING ADVANCED LANGUAGE FEATURES

■ Caution Never instantiate Throwable

,

Exception

, or

Error

. The resulting objects are meaningless because

they are too generic.

在文檔中 Beginning Java 7Get coding with (頁 159-162)