src/share/classes/java/lang/Throwable.java

Print this page

        

@@ -281,10 +281,45 @@
         detailMessage = (cause==null ? null : cause.toString());
         this.cause = cause;
     }
 
     /**
+     * Constructs a new throwable with the specified detail message,
+     * cause, and {@linkplain #addSuppressed suppression} enabled or
+     * disabled.  If suppression is disabled, {@link #getSuppressed}
+     * for this object will return a zero-length array and calls to
+     * {@link #addSuppressed} that would otherwise append an exception
+     * to the suppressed list will have no effect.
+     *
+     * <p>Note that the other constructors of {@code Throwable} treat
+     * suppression as being enabled.  Subclasses of {@code Throwable}
+     * should document any conditions under which suppression is
+     * disabled.  Disabling of suppression should only occur in
+     * exceptional circumstances where special requirements exist,
+     * such as a virtual machine reusing exception objects under
+     * low-memory situations.
+     *
+     * @param  message the detail message.
+     * @param cause the cause.  (A {@code null} value is permitted,
+     * and indicates that the cause is nonexistent or unknown.)
+     * @param enableSuppression whether or not suppression is enabled or disabled
+     *
+     * @see OutOfMemoryError
+     * @see NullPointerException
+     * @see ArithmeticException
+     * @since 1.7
+     */
+    protected Throwable(String message, Throwable cause,
+                        boolean enableSuppression) {
+        fillInStackTrace();
+        detailMessage = message;
+        this.cause = cause;
+        if (!enableSuppression)
+            suppressedExceptions = null;
+    }
+
+    /**
      * Returns the detail message string of this throwable.
      *
      * @return  the detail message string of this {@code Throwable} instance
      *          (which may be {@code null}).
      */

@@ -828,17 +863,14 @@
      * Appends the specified exception to the exceptions that were
      * suppressed in order to deliver this exception. This method is
      * typically called (automatically and implicitly) by the {@code
      * try}-with-resources statement.
      *
-     * If the first exception to be suppressed is {@code null}, that
-     * indicates suppressed exception information will <em>not</em> be
-     * recorded for this exception.  Subsequent calls to this method
-     * will not record any suppressed exceptions.  Otherwise,
-     * attempting to suppress {@code null} after an exception has
-     * already been successfully suppressed results in a {@code
-     * NullPointerException}.
+     * <p>The suppression behavior is enabled <em>unless</em> disabled
+     * {@linkplain #Throwable(String, Throwable, boolean) via a
+     * constructor}.  When suppression is disabled, this method does
+     * nothing other than to validate its argument.
      *
      * <p>Note that when one exception {@linkplain
      * #initCause(Throwable) 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

@@ -872,35 +904,26 @@
      *
      * @param exception the exception to be added to the list of
      *        suppressed exceptions
      * @throws IllegalArgumentException if {@code exception} is this
      *         throwable; a throwable cannot suppress itself.
-     * @throws NullPointerException if {@code exception} is null and
-     *         an exception has already been suppressed by this exception
+     * @throws NullPointerException if {@code exception} is {@code null}
      * @since 1.7
      */
     public final synchronized void addSuppressed(Throwable exception) {
         if (exception == this)
             throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
 
-        if (exception == null) {
-            if (suppressedExceptions == SUPPRESSED_SENTINEL) {
-                suppressedExceptions = null; // No suppression information recorded
-                return;
-            } else
+        if (exception == null)
                 throw new NullPointerException(NULL_CAUSE_MESSAGE);
-        } else {
-            assert exception != null && exception != this;
 
             if (suppressedExceptions == null) // Suppressed exceptions not recorded
                 return;
 
-            if (suppressedExceptions == SUPPRESSED_SENTINEL)
+        if (suppressedExceptions == SUPPRESSED_SENTINEL) {
                 suppressedExceptions = new ArrayList<>(1);
 
-            assert suppressedExceptions != SUPPRESSED_SENTINEL;
-
             suppressedExceptions.add(exception);
         }
     }
 
     private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];

@@ -908,11 +931,13 @@
     /**
      * Returns an array containing all of the exceptions that were
      * suppressed, typically by the {@code try}-with-resources
      * statement, in order to deliver this exception.
      *
-     * If no exceptions were suppressed, an empty array is returned.
+     * If no exceptions were suppressed or {@linkplain
+     * Throwable(String, Throwable, boolean) suppression is disabled},
+     * an empty array is returned.
      *
      * @return an array containing all of the exceptions that were
      *         suppressed to deliver this exception.
      * @since 1.7
      */