Changes Between the Original Proposal and the Public Draft
- Removed the statement that "It is not, in general, possible for the
compiler to enforce a prohibition on side-effects in assertions." It was
pointed out that with sufficient modifications to the language, a compiler
might be able to enforce such a prohibition. A similar change was made to the
statement regarding the use of assertions for argument checking.
- Eliminated the required parentheses from the first form of the call, for
consistency with the return and throw statements. Of course,
parentheses can still be used if desired. Parentheses are still required in
the second form.
- Eliminated the restriction in the second form of the
assert statement that the the second expression must have a reference
type. There was no compelling reason for this restriction, and removing it
provides added convenience, e.g., for developers who want to associate a
unique integer code with each assertion.
- Added subscripts to the expressions in the grammar to clarify exposition.
- If the evaluation of the second ("detail message") expression in the
two-expression form of the assert statement causes an exception to be
thrown, this exception will not be caught, but will propagate outward.
This was previously the case for the first (boolean) expression, but not the
second. The change was made to simplify the semantics of the call and increase
- The second expression in the second form of the assert statement
is converted to a string as per JLS Section 18.104.22.168 to allow for primitive
and null values. This semantics change corresponds to syntax change II.2.
- The semantics was tightened up, and an effort was made to ensure that the
style was similar to that of the other execution specifications in the JLS.
IV. Enabling and Disabling Assertions
- Renamed setAssertionStatus(String className, boolean enabled) to
setClassAssertionStatus(String packageName, boolean enabled) and
setDefaultAssertionStatus(String className, boolean enabled) to
setPackageAssertionStatus(String className, boolean enabled). The new
names are less confusing, as they do not rely on overloading.
- The setClassAssertionStatus method no longer throws an exception
if the specified class has already been loaded. Instead, it returns a boolean
value allowing the caller to determine whether the class will have (or already
has) the desired assertion status. This behavior makes the method easier to
use, especially in the case of low-level system classes, for which it is hard
to predict whether they've already been loaded.
- Modified specification of setClassAssertionStatus(String className,
boolean enabled) to indicate that the named class must be a top-level
class. The nested-class granularity in previous drafts was judged not to be
useful. Further, the implementation in Appendix IV did not work for nested
- The method originally named setDefaultAssertionStatus(String,
boolean) (now named setPackageAssertionStatus(String, boolean))
was erroneously specified to return a boolean value. The return type
has been changed to void.
- Modified setPackageAssertionStatus method to provide support for
"package trees." This allows assertions to be enabled easily in complex
software systems consisting of multiple packages (e.g., Swing).
- Clarified specification for setPackageAssertionStatus to indicate
how to modify the package default assertion status for the unnamed
package that is "current" (JLS 7.4.2). Previously, it was not clear
how to do this, and this functionality is clearly useful.
- Clarified specifications of setPackageAssertionStatus,
setClassAssertionStatus and desiredAssertionStatus to
specify what constitutes an illegal class or package name.
- Documented IllegalArgumentException for all ClassLoader
methods that take a string argument. It is generally a good thing to document
the unchecked exceptions that a method may throw.
- Clarified specification to indicate that all assertion status setting
methods are instance methods on ClassLoader.
- Added specification for desiredAssertionStatus method. This
method may be of little value to programmers but it greatly simplifies the
implementation of the facility. This method was previously discussed in the
"Implementation Notes" section.
- Enlarged the discussion of anonymous classes to apply to all "unnamable"
classes. Other such classes (e.g., local classes) were not addressed by
the original specification.
V. New Error Class
- Removed clazz, file, line and method
arguments from constructor, and removed corresponding accessors from the
class. This functionality will be "moved up the hierarchy" to Throwable, and
will not require the information to be passed into the constructor. It was
decided that this functionality was too useful to be restricted to assertion
errors. Further, it partially duplicated the functionality of stack traces,
which are available for any Throwable.
- Added an AssertionError constructor that takes a detail message. This
constructor was unintentionally omitted from the original proposal.
- Added doc comment for class AssertionError. This comment was
unintentionally omitted from the original proposal.
Appendix I. Usage Notes
- Added this non-normative appendix discussing uses of the facility.
Appendix II. Enabling and Disabling Assertions in the Interpreter
- Added this non-normative appendix describing the facilities that an
interpreter might provide to allow assertions to be enabled and disabled. This
material was previously contained in Section IV. It was moved in order to
segregate all non-normative material in appendices.
- Modified -ea and -da descriptions to use ellipsis
("...") in place of asterisk ("*"), to eliminate the need
for quoting the flag argument in most shells. This also emphasizes the
difference in semantics between this string and the one that occurs in the
import declaration. (The former refers to a package tree, while the
latter refers to a single package.)
- Clarified specification of -ea switch to indicate how to enable
the package default assertion status for the unnamed package that is
"current". This is the interpreter analogue of IV.6.
- The default assertion status for the class loader was erroneously implied
to be "enabled" when describing the command line switches. The specification
was clarified to say that assertions are disabled by default in the
- Added cautionary note concerning the presence of multiple class loaders.
The interpreter must be careful to enable or disable assertions on the correct
Appendix III. Source Compatibility
- Added this non-normative appendix describing a strategy whereby compiler
writers can allow developers to continue using existing programs that use
assert as an identifier.
Appendix IV. Implementation Notes
- Modified the initialization of the synthetic field
($assertionsEnabled) to reflect the fact that
desiredAssertionStatus is an instance method. (This was simply a bug
in the original code.)
- Moved the specification for desiredAssertionStatus(className) to
Section IV. It was decided that it was better to add this function to the
public API, rather than to invoke it via some form of "black magic."
- Added String.valueOf call to the "equivalent code expansion" for
the assertion statement. This is necessary to support primitive
and null values.
- Added do-while loop to "equivalent code expansion," along with
explanation of its purpose. (It causes the equivalent code to have the proper
syntactic category, StatementWithoutTrailingSubstatement.)
Appendix V. Design FAQ
- Added this non-normative appendix to serve as a design rationale.
- Added section numbers, as befits a specification.
- Eliminated "Open Issues" section.