package plume;
// From
// Frequently Asked Questions (with answers) for Java programmers
// Why not use Java's built-in assert statement instead? In general, that
// is better. However, Java's built-in assert can be disabled (yet writing
// "assert" statement can be clearer as to the intention of the test).
// A problem with this is that even if Assert.enabled is false, the
// condition may be evaluated anyway (because it might have side effects).
// How good a job do Java compilers do of eliminating those calls? I
// should do an experiment.
/**
* Assertions: test boolean expressions at runtime.
* @deprecated Use <tt>assert</tt> statement.
*/
@Deprecated
public final class Assert {
private Assert() { throw new Error("do not instantiate"); }
/** If false, the Assert class is disabled. */
public static final boolean enabled = true;
/**
* Throw AssertionException with the argument string
* if the condition does not hold. Named "assertTrue" instead of
* "assert" because "assert" is a Java 1.4 keyword.
**/
public static final void assertTrue(boolean b, /*@Nullable*/ String s) {
if (enabled && !b)
throw new AssertionException(s);
}
/**
* Throw AssertionException if the condition does not hold. Named
* "assertTrue" instead of "assert" because "assert" is a Java 1.4 keyword.
**/
public static final void assertTrue(boolean b) {
assertTrue(b, null);
}
/** Error class for failed assertions. **/
public static final class AssertionException extends Error {
static final long serialVersionUID = 20050923L;
public AssertionException(/*@Nullable*/ String s) {
super(s);
}
}
}
// 6. (Sect. 17) How can I write C/C++ style assertions in Java?
//
// [*] The two classes shown below provide an assertion facility in Java.
// Set Assert.enabled to true to enable the assertions, and to false to
// disable assertions in production code. The AssertionException is not
// meant to be caught--instead, let it print a trace. Since the exception
// is not meant to be caught, we just extend Error instead of
// RuntimeException. As with RuntimeException, a method does not need to
// declare that it throws Error. In addition programmers are less likely
// to write "catch (Error) ..." than "catch (RuntimeException)".
//
// With a good optimizing compiler there will be no run time overhead for
// many uses of these assertions when Assert.enabled is set to false.
// However, if the condition in the assertion may have side effects, the
// condition code cannot be optimized away. For example, in the assertion
//
// Assert.assertTrue(size() <= maxSize, "Maximum size exceeded");
//
// the call to size() cannot be optimized away unless the compiler can see
// that the call has no side effects. C and C++ use the preprocessor to
// guarantee that assertions will never cause overhead in production code.
// Without a preprocessor, it seems the best we can do in Java is to write
//
// Assert.assertTrue(Assert.enabled && size() <= maxSize, "Too big");
//
// Alternatively, use
//
// if (Assert.enabled)
// Assert.assertTrue( size() <= maxSize, "Too big" );
//
// In this case, when Assert.enabled is false, the method call can always
// be optimized away totally, even if it has side effects. The relevant
// sections of the JLS are Section 13.4.8, final Fields and Constants and
// Section 14.19, Unreachable Statements. 13.4.8 requires that primitive
// constants ("a field that is static, final, and initialized with a
// compile-time constant expression") be inlined. So everywhere
// Assert.enabled is refered it is replaced at compile time with its
// value. Writing:
//
// if (Assert.enabled) Assert.assertTrue(size() <= maxSize, "Too big");
//
// is exactly the same as writing:
//
// if (false) Assert.assertTrue(size() <= maxSize, "Too big");
//
// ... assuming Assert.enabled is false at compile time. Section 14.19
// discusses compiling away such dead code. To sum up: the inlining of the
// primitive constant is required by the spec. The subsequent optimization
// of not generating code masked by (what turns into) an "if (false) ..."
// is not required but is implemented by many existing Java compilers.
//
// public class AssertionException extends Error {
// public AssertionException(String s) {
// super(s);
// }
// }
//
// public final class Assert {
// public static final boolean enabled = true;
// public static final void assert(boolean b, String s) {
// if (enabled && !b)
// throw new AssertionException(s);
// }
// }