138

What does assert do? For example in the function:

private static int charAt(String s, int d) {
    assert d >= 0 && d <= s.length();
    if (d == s.length()) return -1;
    return s.charAt(d);
}
spongebob
  • 8,370
  • 15
  • 50
  • 83
Peiska
  • 1,789
  • 4
  • 17
  • 15

8 Answers8

240

If you launch your program with -enableassertions (or -ea for short) then this statement

assert cond;

is equivalent to

if (!cond)
    throw new AssertionError();

If you launch your program without this option, the assert statement will have no effect.

For example, assert d >= 0 && d <= s.length();, as posted in your question, is equivalent to

if (!(d >= 0 && d <= s.length()))
    throw new AssertionError();

(If you launched with -enableassertions that is.)


Formally, the Java Language Specification: 14.10. The assert Statement says the following:

14.10. The assert Statement
An assertion is an assert statement containing a boolean expression. An assertion is either enabled or disabled. If the assertion is enabled, execution of the assertion causes evaluation of the boolean expression and an error is reported if the expression evaluates to false. If the assertion is disabled, execution of the assertion has no effect whatsoever.

Where "enabled or disabled" is controlled with the -ea switch and "An error is reported" means that an AssertionError is thrown.


And finally, a lesser known feature of assert:

You can append : "Error message" like this:

assert d != null : "d is null";

to specify what the error message of the thrown AssertionError should be.


This post has been rewritten as an article here.

aioobe
  • 413,195
  • 112
  • 811
  • 826
  • 5
    Agreed, asserts should not be used to ensure argument validity but to point out strong assumptions. – whiskeysierra Jun 10 '10 at 21:57
  • 20
    Using `assert` to test a **non public** method's [precondition](http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html#preconditions) is perfectly valid IMO. – Pascal Thivent Jun 10 '10 at 22:28
  • 2
    Using assert is the good style of coding if it's the client's responsibility to ensure the arguments are within range. As argued by Bertrand Meyer (design by contract) this assumption avoids duplicate checking. Using IllegalArgumentException is the good style in a public API. See also this [answer](http://stackoverflow.com/questions/5049163/when-should-i-use-apache-commons-validate-istrue-and-when-should-i-just-use-the/5452329#5452329) to a related stackoverflow question. – avandeursen Apr 03 '11 at 15:36
  • I see assert in java much like the debug macro's as found in c or c++. If you run some very large tests you can use them. But you can leave them out when you 'run' the application, and as such you get faster performance. I don't see it really used as argument variable checking but more deeper into code where various variables can be checked. Like ' did we do 4 or 5 loops where only 4 was expected under all conditions. – R. van Twisk Feb 22 '14 at 23:55
  • should we remove code containing `assert` from production code ? – Qbik Jul 04 '16 at 15:48
  • How to add `-enableassertions` in Android Studio debug configuration? – Felix Oct 09 '16 at 07:57
  • @Qbik You don't need to; just run without `-enableassertions` in production, as mentioned above. – Franklin Yu Jan 03 '17 at 03:16
12

If the condition isn't satisfied, an AssertionError will be thrown.

Assertions have to be enabled, though; otherwise the assert expression does nothing. See:

http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html#enable-disable

Richard Fearn
  • 25,073
  • 7
  • 56
  • 55
5

Although I have read a lot documentation about this one, I'm still confusing on how, when, and where to use it.

Make it very simple to understand:

When you have a similar situation like this:

    String strA = null;
    String strB = null;
    if (2 > 1){
        strA = "Hello World";
    }

    strB = strA.toLowerCase(); 

You might receive warning (displaying yellow line on strB = strA.toLowerCase(); ) that strA might produce a NULL value to strB. Although you know that strB is absolutely won't be null in the end, just in case, you use assert to

1. Disable the warning.

2. Throw Exception error IF worst thing happens (when you run your application).

Sometime, when you compile your code, you don't get your result and it's a bug. But the application won't crash, and you spend a very hard time to find where is causing this bug.

So, if you put assert, like this:

    assert strA != null; //Adding here
    strB = strA .toLowerCase();

you tell the compiler that strA is absolutely not a null value, it can 'peacefully' turn off the warning. IF it is NULL (worst case happens), it will stop the application and throw a bug to you to locate it.

felixwcf
  • 2,078
  • 1
  • 28
  • 45
5

assert is a debugging tool that will cause the program to throw an AssertionFailed exception if the condition is not true. In this case, the program will throw an exception if either of the two conditions following it evaluate to false. Generally speaking, assert should not be used in production code

Chris Thompson
  • 35,167
  • 12
  • 80
  • 109
  • 1
    It doesn't necessarily cause the program to crash. You can, in fact, catch an `AssertionError`, just like any other exception. – Richard Fearn Jun 10 '10 at 21:39
  • 5
    And since assertions need to be explicitly enabled to have any effect, having them in production code doesn't hurt. – meriton Jun 10 '10 at 21:40
  • Ah my mistake, is it in C then that they are more troublesome? That could be where I'm remembering that paradigm from... – Chris Thompson Jun 10 '10 at 21:56
  • 1
    Well I must say I agree. Java asserts should not be used in production code. I.e. the client should not be told to launch with the `-ea` switch. – aioobe Jun 10 '10 at 22:02
1

Use this version of the assert statement to provide a detail message for the AssertionError. The system passes the value of Expression2 to the appropriate AssertionError constructor, which uses the string representation of the value as the error's detail message.

The purpose of the detail message is to capture and communicate the details of the assertion failure. The message should allow you to diagnose and ultimately fix the error that led the assertion to fail. Note that the detail message is not a user-level error message, so it is generally unnecessary to make these messages understandable in isolation, or to internationalize them. The detail message is meant to be interpreted in the context of a full stack trace, in conjunction with the source code containing the failed assertion.

JavaDoc

Community
  • 1
  • 1
Jan K.
  • 1,607
  • 2
  • 13
  • 22
1

Assertions are generally used primarily as a means of checking the program's expected behavior. It should lead to a crash in most cases, since the programmer's assumptions about the state of the program are false. This is where the debugging aspect of assertions come in. They create a checkpoint that we simply can't ignore if we would like to have correct behavior.

In your case it does data validation on the incoming parameters, though it does not prevent clients from misusing the function in the future. Especially if they are not, (and should not) be included in release builds.

Zoli
  • 1,137
  • 7
  • 12
0

It ensures that the expression returns true. Otherwise, it throws a java.lang.AssertionError.

http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.10

Brett Kail
  • 33,593
  • 2
  • 85
  • 90
0

Assert does throw an AssertionError if you run your app with assertions turned on.

int a = 42;
assert a >= 0 && d <= 10;

If you run this with, say: java -ea -jar peiska.jar

It shall throw an java.lang.AssertionError

NoozNooz42
  • 4,238
  • 6
  • 33
  • 53