112 * @since JDK1.0
113 */
114 public class Throwable implements Serializable {
115 /** use serialVersionUID from JDK 1.0.2 for interoperability */
116 private static final long serialVersionUID = -3042686055658047285L;
117
118 /**
119 * Native code saves some indication of the stack backtrace in this slot.
120 */
121 private transient Object backtrace;
122
123 /**
124 * Specific details about the Throwable. For example, for
125 * {@code FileNotFoundException}, this contains the name of
126 * the file that could not be found.
127 *
128 * @serial
129 */
130 private String detailMessage;
131
132 /**
133 * A shared value for an empty stack.
134 */
135 private static final StackTraceElement[] EMPTY_STACK = new StackTraceElement[0];
136
137 /*
138 * To allow Throwable objects to be made immutable and safely
139 * reused by the JVM, such as OutOfMemoryErrors, fields of
140 * Throwable that are writable in response to user actions, cause
141 * and suppressedExceptions obey the following protocol:
142 *
143 * 1) The fields are initialized to a non-null sentinel value
144 * which indicates the value has logically not been set.
145 *
146 * 2) Writing a null to the field indicates further writes
147 * are forbidden
148 *
149 * 3) The sentinel value may be replaced with another non-null
150 * value.
151 *
152 * For example, implementations of the HotSpot JVM have
153 * preallocated OutOfMemoryError objects to provide for better
154 * diagnosability of that situation. These objects are created
155 * without calling the constructor for that class and the fields
156 * in question are initialized to null. To support this
157 * capability, any new fields added to Throwable that require
158 * being initialized to a non-null value require a coordinated JVM
159 * change.
160 */
161
162 /**
163 * The throwable that caused this throwable to get thrown, or null if this
164 * throwable was not caused by another throwable, or if the causative
165 * throwable is unknown. If this field is equal to this throwable itself,
166 * it indicates that the cause of this throwable has not yet been
167 * initialized.
168 *
169 * @serial
170 * @since 1.4
171 */
172 private Throwable cause = this;
173
174 /**
175 * The stack trace, as returned by {@link #getStackTrace()}.
176 *
177 * @serial
178 * @since 1.4
179 */
180 private StackTraceElement[] stackTrace;
181
182 // Setting this static field introduces an acceptable
183 // initialization dependency on a few java.util classes.
184 private static final List<Throwable> SUPPRESSED_SENTINEL =
185 Collections.unmodifiableList(new ArrayList<Throwable>(0));
186
187 /**
188 * The list of suppressed exceptions, as returned by {@link
189 * #getSuppressed()}. The list is initialized to a zero-element
190 * unmodifiable sentinel list. When a serialized Throwable is
191 * read in, if the {@code suppressedExceptions} field points to a
192 * zero-element list, the field is reset to the sentinel value.
193 *
194 * @serial
195 * @since 1.7
196 */
197 private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL;
198
199 /** Message for trying to suppress a null exception. */
200 private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
690 private final PrintWriter printWriter;
691
692 WrappedPrintWriter(PrintWriter printWriter) {
693 this.printWriter = printWriter;
694 }
695
696 Object lock() {
697 return printWriter;
698 }
699
700 void println(Object o) {
701 printWriter.println(o);
702 }
703 }
704
705 /**
706 * Fills in the execution stack trace. This method records within this
707 * {@code Throwable} object information about the current state of
708 * the stack frames for the current thread.
709 *
710 * @return a reference to this {@code Throwable} instance.
711 * @see java.lang.Throwable#printStackTrace()
712 */
713 public synchronized native Throwable fillInStackTrace();
714
715 /**
716 * Provides programmatic access to the stack trace information printed by
717 * {@link #printStackTrace()}. Returns an array of stack trace elements,
718 * each representing one stack frame. The zeroth element of the array
719 * (assuming the array's length is non-zero) represents the top of the
720 * stack, which is the last method invocation in the sequence. Typically,
721 * this is the point at which this throwable was created and thrown.
722 * The last element of the array (assuming the array's length is non-zero)
723 * represents the bottom of the stack, which is the first method invocation
724 * in the sequence.
725 *
726 * <p>Some virtual machines may, under some circumstances, omit one
727 * or more stack frames from the stack trace. In the extreme case,
728 * a virtual machine that has no stack trace information concerning
729 * this throwable is permitted to return a zero-length array from this
730 * method. Generally speaking, the array returned by this method will
731 * contain one element for every frame that would be printed by
732 * {@code printStackTrace}.
733 *
734 * @return an array of stack trace elements representing the stack trace
735 * pertaining to this throwable.
736 * @since 1.4
737 */
738 public StackTraceElement[] getStackTrace() {
739 return getOurStackTrace().clone();
740 }
741
742 private synchronized StackTraceElement[] getOurStackTrace() {
743 // Initialize stack trace if this is the first call to this method
744 if (stackTrace == null) {
745 int depth = getStackTraceDepth();
746 stackTrace = new StackTraceElement[depth];
747 for (int i=0; i < depth; i++)
748 stackTrace[i] = getStackTraceElement(i);
749 }
750 return stackTrace;
751 }
752
753 /**
754 * Sets the stack trace elements that will be returned by
755 * {@link #getStackTrace()} and printed by {@link #printStackTrace()}
756 * and related methods.
757 *
758 * This method, which is designed for use by RPC frameworks and other
759 * advanced systems, allows the client to override the default
760 * stack trace that is either generated by {@link #fillInStackTrace()}
761 * when a throwable is constructed or deserialized when a throwable is
762 * read from a serialization stream.
763 *
764 * @param stackTrace the stack trace elements to be associated with
765 * this {@code Throwable}. The specified array is copied by this
766 * call; changes in the specified array after the method invocation
767 * returns will have no affect on this {@code Throwable}'s stack
768 * trace.
769 *
770 * @throws NullPointerException if {@code stackTrace} is
771 * {@code null}, or if any of the elements of
772 * {@code stackTrace} are {@code null}
773 *
774 * @since 1.4
775 */
776 public void setStackTrace(StackTraceElement[] stackTrace) {
777 StackTraceElement[] defensiveCopy = stackTrace.clone();
778 for (int i = 0; i < defensiveCopy.length; i++)
779 if (defensiveCopy[i] == null)
780 throw new NullPointerException("stackTrace[" + i + "]");
781
782 synchronized (this) {
783 this.stackTrace = defensiveCopy;
784 }
785 }
786
787 /**
788 * Returns the number of elements in the stack trace (or 0 if the stack
789 * trace is unavailable).
790 *
791 * package-protection for use by SharedSecrets.
792 */
793 native int getStackTraceDepth();
794
795 /**
796 * Returns the specified element of the stack trace.
797 *
798 * package-protection for use by SharedSecrets.
799 *
800 * @param index index of the element to return.
801 * @throws IndexOutOfBoundsException if {@code index < 0 ||
802 * index >= getStackTraceDepth() }
803 */
804 native StackTraceElement getStackTraceElement(int index);
805
806 /**
807 * Reads a {@code Throwable} from a stream, enforcing
808 * well-formedness constraints on fields. Null entries and
809 * self-pointers are not allowed in the list of {@code
810 * suppressedExceptions}. Null entries are not allowed for stack
811 * trace elements.
812 *
813 * Note that there are no constraints on the value the {@code
814 * cause} field can hold; both {@code null} and {@code this} are
815 * valid values for the field.
816 */
817 private void readObject(ObjectInputStream s)
818 throws IOException, ClassNotFoundException {
819 s.defaultReadObject(); // read in all fields
820 if (suppressedExceptions != null) {
821 List<Throwable> suppressed = null;
822 if (suppressedExceptions.isEmpty()) {
823 // Use the sentinel for a zero-length list
824 suppressed = SUPPRESSED_SENTINEL;
825 } else { // Copy Throwables to new list
826 suppressed = new ArrayList<>(1);
827 for (Throwable t : suppressedExceptions) {
828 // Enforce constraints on suppressed exceptions in
829 // case of corrupt or malicious stream.
830 if (t == null)
831 throw new NullPointerException(NULL_CAUSE_MESSAGE);
832 if (t == this)
833 throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
834 suppressed.add(t);
835 }
836 }
837 suppressedExceptions = suppressed;
838 } // else a null suppressedExceptions field remains null
839
840 if (stackTrace != null) {
841 for (StackTraceElement ste : stackTrace) {
842 if (ste == null)
843 throw new NullPointerException("null StackTraceElement in serial stream. ");
844 }
845 } else {
846 // A null stackTrace field in the serial form can result from
847 // an exception serialized without that field in older JDK releases.
848 stackTrace = EMPTY_STACK;
849 }
850
851 }
852
853 /**
854 * Write a {@code Throwable} object to a stream.
855 */
856 private synchronized void writeObject(ObjectOutputStream s)
857 throws IOException {
858 getOurStackTrace(); // Ensure that stackTrace field is initialized.
859 s.defaultWriteObject();
860 }
861
862 /**
863 * Appends the specified exception to the exceptions that were
864 * suppressed in order to deliver this exception. This method is
865 * typically called (automatically and implicitly) by the {@code
866 * try}-with-resources statement.
867 *
868 * <p>The suppression behavior is enabled <em>unless</em> disabled
869 * {@linkplain #Throwable(String, Throwable, boolean) via a
870 * constructor}. When suppression is disabled, this method does
871 * nothing other than to validate its argument.
872 *
873 * <p>Note that when one exception {@linkplain
874 * #initCause(Throwable) causes} another exception, the first
875 * exception is usually caught and then the second exception is
876 * thrown in response. In other words, there is a causal
877 * connection between the two exceptions.
878 *
879 * In contrast, there are situations where two independent
916 if (exception == null)
917 throw new NullPointerException(NULL_CAUSE_MESSAGE);
918
919 if (suppressedExceptions == null) // Suppressed exceptions not recorded
920 return;
921
922 if (suppressedExceptions == SUPPRESSED_SENTINEL)
923 suppressedExceptions = new ArrayList<>(1);
924
925 suppressedExceptions.add(exception);
926 }
927
928 private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
929
930 /**
931 * Returns an array containing all of the exceptions that were
932 * suppressed, typically by the {@code try}-with-resources
933 * statement, in order to deliver this exception.
934 *
935 * If no exceptions were suppressed or {@linkplain
936 * Throwable(String, Throwable, boolean) suppression is disabled},
937 * an empty array is returned.
938 *
939 * @return an array containing all of the exceptions that were
940 * suppressed to deliver this exception.
941 * @since 1.7
942 */
943 public final synchronized Throwable[] getSuppressed() {
944 if (suppressedExceptions == SUPPRESSED_SENTINEL ||
945 suppressedExceptions == null)
946 return EMPTY_THROWABLE_ARRAY;
947 else
948 return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
949 }
950 }
|
112 * @since JDK1.0
113 */
114 public class Throwable implements Serializable {
115 /** use serialVersionUID from JDK 1.0.2 for interoperability */
116 private static final long serialVersionUID = -3042686055658047285L;
117
118 /**
119 * Native code saves some indication of the stack backtrace in this slot.
120 */
121 private transient Object backtrace;
122
123 /**
124 * Specific details about the Throwable. For example, for
125 * {@code FileNotFoundException}, this contains the name of
126 * the file that could not be found.
127 *
128 * @serial
129 */
130 private String detailMessage;
131
132
133 /**
134 * Holder class to defer initializing sentinel objects only used
135 * for serialization.
136 */
137 private static class SentinelHolder {
138 /**
139 * {@linkplain #setStackTrace(StackTraceElement[]) Setting the
140 * stack trace} to a one-element array containing this sentinel
141 * value indicates future attempts to set the stack trace will be
142 * ignored. The sentinal is equal to the result of calling:<br>
143 * {@code new StackTraceElement("", "", null, Integer.MIN_VALUE)}
144 */
145 public static final StackTraceElement STACK_TRACE_ELEMENT_SENTINEL =
146 new StackTraceElement("", "", null, Integer.MIN_VALUE);
147
148 /**
149 * Sentinel value used in the serial form to indicate an immutable
150 * stack trace.
151 */
152 public static final StackTraceElement[] STACK_TRACE_SENTINEL =
153 new StackTraceElement[] {STACK_TRACE_ELEMENT_SENTINEL};
154 }
155
156 /**
157 * A value indicating the stack trace field has not yet been initialized.
158 */
159 private static final StackTraceElement[] UNINITIALIZED_STACK =
160 new StackTraceElement[] {new StackTraceElement("UNINITIALIZED", "STACK", null, -1)};
161
162 /**
163 * A value indicating that the logical stack trace has been
164 * populated into the backtrace field.
165 */
166 private static final StackTraceElement[] FILLED_IN_STACK =
167 new StackTraceElement[] {new StackTraceElement("FILLED_IN", "STACK", null, -1)};
168
169 /**
170 * A shared value for an empty stack.
171 */
172 private static final StackTraceElement[] EMPTY_STACK = new StackTraceElement[0];
173
174 /*
175 * To allow Throwable objects to be made immutable and safely
176 * reused by the JVM, such as OutOfMemoryErrors, fields of
177 * Throwable that are writable in response to user actions, cause,
178 * stackTrace, and suppressedExceptions obey the following
179 * protocol:
180 *
181 * 1) The fields are initialized to a non-null sentinel value
182 * which indicates the value has logically not been set.
183 *
184 * 2) Writing a null to the field indicates further writes
185 * are forbidden
186 *
187 * 3) The sentinel value may be replaced with another non-null
188 * value.
189 *
190 * For example, implementations of the HotSpot JVM have
191 * preallocated OutOfMemoryError objects to provide for better
192 * diagnosability of that situation. These objects are created
193 * without calling the constructor for that class and the fields
194 * in question are initialized to null. To support this
195 * capability, any new fields added to Throwable that require
196 * being initialized to a non-null value require a coordinated JVM
197 * change.
198 */
199
200 /**
201 * The throwable that caused this throwable to get thrown, or null if this
202 * throwable was not caused by another throwable, or if the causative
203 * throwable is unknown. If this field is equal to this throwable itself,
204 * it indicates that the cause of this throwable has not yet been
205 * initialized.
206 *
207 * @serial
208 * @since 1.4
209 */
210 private Throwable cause = this;
211
212 /**
213 * The stack trace, as returned by {@link #getStackTrace()}.
214 *
215 * The field is initialized to a zero-length array. A {@code
216 * null} value of this field indicates subsequent calls to {@link
217 * #setStackTrace()} and {@link #fillInStackTrace} will be be no-ops.
218 *
219 * @serial
220 * @since 1.4
221 */
222 private StackTraceElement[] stackTrace = UNINITIALIZED_STACK;
223
224 // Setting this static field introduces an acceptable
225 // initialization dependency on a few java.util classes.
226 private static final List<Throwable> SUPPRESSED_SENTINEL =
227 Collections.unmodifiableList(new ArrayList<Throwable>(0));
228
229 /**
230 * The list of suppressed exceptions, as returned by {@link
231 * #getSuppressed()}. The list is initialized to a zero-element
232 * unmodifiable sentinel list. When a serialized Throwable is
233 * read in, if the {@code suppressedExceptions} field points to a
234 * zero-element list, the field is reset to the sentinel value.
235 *
236 * @serial
237 * @since 1.7
238 */
239 private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL;
240
241 /** Message for trying to suppress a null exception. */
242 private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
732 private final PrintWriter printWriter;
733
734 WrappedPrintWriter(PrintWriter printWriter) {
735 this.printWriter = printWriter;
736 }
737
738 Object lock() {
739 return printWriter;
740 }
741
742 void println(Object o) {
743 printWriter.println(o);
744 }
745 }
746
747 /**
748 * Fills in the execution stack trace. This method records within this
749 * {@code Throwable} object information about the current state of
750 * the stack frames for the current thread.
751 *
752 * <p>If the stack trace of this {@code Throwable} {@linkplain
753 * Throwable#setStackTrace(StackTraceElement[]) has been set} to
754 * {@code null}, calling this method has no effect.
755 *
756 * @return a reference to this {@code Throwable} instance.
757 * @see java.lang.Throwable#printStackTrace()
758 */
759 public synchronized Throwable fillInStackTrace() {
760 if (stackTrace != null) {
761 fillInStackTrace(0);
762 stackTrace = FILLED_IN_STACK;
763 }
764 return this;
765 }
766
767 private native Throwable fillInStackTrace(int dummy);
768
769 /**
770 * Provides programmatic access to the stack trace information printed by
771 * {@link #printStackTrace()}. Returns an array of stack trace elements,
772 * each representing one stack frame. The zeroth element of the array
773 * (assuming the array's length is non-zero) represents the top of the
774 * stack, which is the last method invocation in the sequence. Typically,
775 * this is the point at which this throwable was created and thrown.
776 * The last element of the array (assuming the array's length is non-zero)
777 * represents the bottom of the stack, which is the first method invocation
778 * in the sequence.
779 *
780 * <p>Some virtual machines may, under some circumstances, omit one
781 * or more stack frames from the stack trace. In the extreme case,
782 * a virtual machine that has no stack trace information concerning
783 * this throwable is permitted to return a zero-length array from this
784 * method. Generally speaking, the array returned by this method will
785 * contain one element for every frame that would be printed by
786 * {@code printStackTrace}.
787 *
788 * @return an array of stack trace elements representing the stack trace
789 * pertaining to this throwable.
790 * @since 1.4
791 */
792 public StackTraceElement[] getStackTrace() {
793 return getOurStackTrace().clone();
794 }
795
796 private synchronized StackTraceElement[] getOurStackTrace() {
797 // Initialize stack trace field with information from
798 // backtrace if this is the first call to this method
799 if (stackTrace == FILLED_IN_STACK) {
800 int depth = getStackTraceDepth();
801 stackTrace = new StackTraceElement[depth];
802 for (int i=0; i < depth; i++)
803 stackTrace[i] = getStackTraceElement(i);
804 } else if (stackTrace == null) {
805 return EMPTY_STACK;
806 }
807 return stackTrace;
808 }
809
810 /**
811 * Sets the stack trace elements that will be returned by
812 * {@link #getStackTrace()} and printed by {@link #printStackTrace()}
813 * and related methods.
814 *
815 * This method, which is designed for use by RPC frameworks and other
816 * advanced systems, allows the client to override the default
817 * stack trace that is either generated by {@link #fillInStackTrace()}
818 * when a throwable is constructed or deserialized when a throwable is
819 * read from a serialization stream.
820 *
821 * <p>If the stack trace is set to {@code null}, then future calls
822 * to this method have no effect on this {@code Throwable}.
823 *
824 * @param stackTrace the stack trace elements to be associated with
825 * this {@code Throwable}. The specified array is copied by this
826 * call; changes in the specified array after the method invocation
827 * returns will have no affect on this {@code Throwable}'s stack
828 * trace.
829 *
830 * @throws NullPointerException if any of the elements of
831 * {@code stackTrace} are {@code null}
832 *
833 * @since 1.4
834 */
835 public void setStackTrace(StackTraceElement[] stackTrace) {
836 if (this.stackTrace == null) // Immutable stack
837 return;
838
839 StackTraceElement[] defensiveCopy;
840
841 if (stackTrace == null) {
842 defensiveCopy = stackTrace;
843 } else {
844 defensiveCopy = stackTrace.clone();
845
846 for (int i = 0; i < defensiveCopy.length; i++) {
847 if (defensiveCopy[i] == null)
848 throw new NullPointerException("stackTrace[" + i + "]");
849 }
850 }
851
852 synchronized (this) {
853 this.stackTrace = defensiveCopy;
854 }
855 }
856
857 /**
858 * Returns the number of elements in the stack trace (or 0 if the stack
859 * trace is unavailable).
860 *
861 * package-protection for use by SharedSecrets.
862 */
863 native int getStackTraceDepth();
864
865 /**
866 * Returns the specified element of the stack trace.
867 *
868 * package-protection for use by SharedSecrets.
869 *
870 * @param index index of the element to return.
871 * @throws IndexOutOfBoundsException if {@code index < 0 ||
872 * index >= getStackTraceDepth() }
873 */
874 native StackTraceElement getStackTraceElement(int index);
875
876 /**
877 * Reads a {@code Throwable} from a stream, enforcing
878 * well-formedness constraints on fields. Null entries and
879 * self-pointers are not allowed in the list of {@code
880 * suppressedExceptions}. Null entries are not allowed for stack
881 * trace elements. A single-element stack trace whose entry is
882 * equal to {@code new StackTraceElement("", "", null,
883 * Integer.MIN_VALUE)} results in a {@code null} {@code
884 * stackTrace} field.
885 *
886 * Note that there are no constraints on the value the {@code
887 * cause} field can hold; both {@code null} and {@code this} are
888 * valid values for the field.
889 */
890 private void readObject(ObjectInputStream s)
891 throws IOException, ClassNotFoundException {
892 s.defaultReadObject(); // read in all fields
893 if (suppressedExceptions != null) {
894 List<Throwable> suppressed = null;
895 if (suppressedExceptions.isEmpty()) {
896 // Use the sentinel for a zero-length list
897 suppressed = SUPPRESSED_SENTINEL;
898 } else { // Copy Throwables to new list
899 suppressed = new ArrayList<>(1);
900 for (Throwable t : suppressedExceptions) {
901 // Enforce constraints on suppressed exceptions in
902 // case of corrupt or malicious stream.
903 if (t == null)
904 throw new NullPointerException(NULL_CAUSE_MESSAGE);
905 if (t == this)
906 throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
907 suppressed.add(t);
908 }
909 }
910 suppressedExceptions = suppressed;
911 } // else a null suppressedExceptions field remains null
912
913 // Check for the marker of an immutable stack trace
914 if (stackTrace != null) {
915 // Share zero-length stack traces
916 if (stackTrace.length == 0) {
917 stackTrace = EMPTY_STACK;
918 } else if (stackTrace.length == 1 &&
919 SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) {
920 stackTrace = null;
921 } else { // Verify stack trace elements are non-null.
922 for(StackTraceElement ste : stackTrace) {
923 if (ste == null)
924 throw new NullPointerException("null StackTraceElement in serial stream. ");
925 }
926 }
927 }
928 // A null stackTrace field in the serial form can result from
929 // an exception serialized without that field. Such exceptions
930 // are now treated as having immutable stack traces.
931 }
932
933 /**
934 * Write a {@code Throwable} object to a stream.
935 *
936 * A {@code null} stack trace field is represented in the serial
937 * form as a one-element array whose element is equal to {@code
938 * new StackTraceElement("", "", null, Integer.MIN_VALUE)}.
939 */
940 private synchronized void writeObject(ObjectOutputStream s)
941 throws IOException {
942 // Ensure that the stackTrace field is initialized to a
943 // non-null value, if appropriate. As of JDK 7, a null stack
944 // trace field is a valid value indicating the stack trace
945 // should not be set.
946 getOurStackTrace();
947 ObjectOutputStream.PutField fields = s.putFields();
948
949 fields.put("detailMessage", detailMessage);
950 fields.put("cause", cause);
951 // Serialize a null stacktrace using the stack trace sentinel.
952 if (stackTrace == null)
953 fields.put("stackTrace", SentinelHolder.STACK_TRACE_SENTINEL);
954 else
955 fields.put("stackTrace", stackTrace);
956 fields.put("suppressedExceptions", suppressedExceptions);
957
958 s.writeFields();
959 }
960
961 /**
962 * Appends the specified exception to the exceptions that were
963 * suppressed in order to deliver this exception. This method is
964 * typically called (automatically and implicitly) by the {@code
965 * try}-with-resources statement.
966 *
967 * <p>The suppression behavior is enabled <em>unless</em> disabled
968 * {@linkplain #Throwable(String, Throwable, boolean) via a
969 * constructor}. When suppression is disabled, this method does
970 * nothing other than to validate its argument.
971 *
972 * <p>Note that when one exception {@linkplain
973 * #initCause(Throwable) causes} another exception, the first
974 * exception is usually caught and then the second exception is
975 * thrown in response. In other words, there is a causal
976 * connection between the two exceptions.
977 *
978 * In contrast, there are situations where two independent
1015 if (exception == null)
1016 throw new NullPointerException(NULL_CAUSE_MESSAGE);
1017
1018 if (suppressedExceptions == null) // Suppressed exceptions not recorded
1019 return;
1020
1021 if (suppressedExceptions == SUPPRESSED_SENTINEL)
1022 suppressedExceptions = new ArrayList<>(1);
1023
1024 suppressedExceptions.add(exception);
1025 }
1026
1027 private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
1028
1029 /**
1030 * Returns an array containing all of the exceptions that were
1031 * suppressed, typically by the {@code try}-with-resources
1032 * statement, in order to deliver this exception.
1033 *
1034 * If no exceptions were suppressed or {@linkplain
1035 * #Throwable(String, Throwable, boolean) suppression is disabled},
1036 * an empty array is returned.
1037 *
1038 * @return an array containing all of the exceptions that were
1039 * suppressed to deliver this exception.
1040 * @since 1.7
1041 */
1042 public final synchronized Throwable[] getSuppressed() {
1043 if (suppressedExceptions == SUPPRESSED_SENTINEL ||
1044 suppressedExceptions == null)
1045 return EMPTY_THROWABLE_ARRAY;
1046 else
1047 return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
1048 }
1049 }
|