What are some real life examples to understand the key role of the Java assert
keyword?

- 3,119
- 19
- 19
- 37

- 90,477
- 74
- 177
- 219
-
11In real life you almost never see them. Conjecture: If you use assertions you have to think about three states: Assert passes, assert fails, assert is turned off, instead of just two. And assert is turned off by default so that is the most likely state, and it is hard to ensure that it is enabled for your code. What that adds up to is that asserts are a premature optimization that would be of limited use. As you see in @Bjorn's answer, it is even hard to come up with a use case where you would not want to fail an assert all the time. – Yishai May 03 '10 at 14:33
-
42@Yishai: _"you have to think about ... assert is turned off"_ If you need to do that, you are doing it wrong. _"asserts are a premature optimization of limited use"_ This is pretty much off the rails. Here is Sun's take on this: "[Using Assertions in Java Technology](http://www.oracle.com/us/technologies/java/assertions-139853.html)" and this is also good to read: "[The benefits of programming with assertions (a.k.a. assert statements)](http://www.pgbovine.net/programming-with-asserts.htm)" – David Tonhofer Jan 23 '14 at 13:41
-
6@DavidTonhofer, in real life you almost never see them. This is verifiable. Check as many open source projects as you like. I'm not saying you don't validate invariants. That isn't the same thing. Put another way. If asserts are so important, why are they off by default? – Yishai Jan 23 '14 at 14:22
-
3@Yishai: This unfortunately says more about the people doing the programming than about the assertions: a lack of basic programming hygiene. I say this because I have seen tons of code where the programmer was unable or unwilling to add an assertion because _he simply didn't know what he was doing in the first place_, leaving lots of edge cases uncovered and entering demented inner state like an off-road vehicle with taped-over windows. Lots of code I saw also evoked lengthy "huh? did he think about this case..." reflections which could have dispelled in an instant by an appropriate "assert". – David Tonhofer Jan 24 '14 at 01:08
-
19A reference, FWIW: [The relationship between software assertions and code quality](http://www.embedded.com/electrical-engineer-community/general/4416085/The-relationship-between-software-assertions-and-code-quality): _"We also compare the efficacy of assertions against that of popular bug finding techniques like source code static analysis tools. We observe from our case study that with an increase in the assertion density in a file there is a statistically significant decrease in fault density."_ – David Tonhofer Jan 24 '14 at 01:10
-
@DavidTonhofer, You aren't defending asserts which you do not want to fail all the time, which is all the assert keyword is good for. – Yishai Jan 24 '14 at 14:24
-
2@Yiashai That is the point of "assert". It "asserts" that something is true at some point in the program state, so it expresses an assumption about how the program is supposed to work. **If the assertion is violated, you are in presence of a fatal error**. If you mean to say that it is not powerful enough, and that you want Contracts (like C4J), I can agree with that. – David Tonhofer Jan 27 '14 at 07:56
-
5@DavidTonhofer David, i think your love for assertion is for a very specific type of programming that you guys are doing, in my field which works with web applications exiting out of the program for ANY reason is the biggest NO NO - i have personally never used assert other than unit/integ testing – nightograph Jun 05 '14 at 15:56
-
@nightograph For sure, I do not like the thrown Error and have been using a catchable RuntimeException myself. In case of webapps, I caughteverything at the servlet level and invoked default behaviour when SHTF, which of course should not happen in production code (if a serious problem occurs when transferring money from one account to another, say, I consider it best to ferry the user to an excuse&login screen... YMMV). Of course, if the problem occurs in the servlet engine, uglyness ensues regardless. – David Tonhofer Jun 06 '14 at 16:31
-
6Assertions can be turned off. This mean you are not guaranteed that they will "fire" in production, which is where you need it most. – Thorbjørn Ravn Andersen Jan 03 '16 at 17:17
-
@Yiashai Assertions are off by default so they will most likely be off in production, which is the right way to use them. They're strictly a development phase tool. They're very helpful in catching bugs in development, which is where you're most likely to see bugs. – MiguelMunoz Oct 24 '19 at 23:12
-
In web applications, where exiting for any reason is the biggest NO NO, assertions are still useful. First of all, any of today's web frameworks will catch the AssertionError and return a 500-InternalServerError result, then will continue servicing requests. Second, you should leave them off in production anyway, so they can't get triggered. I find assertions very useful in web development. I turn them on when I'm testing my changes and running my unit tests. I'm very finicky, so I even run my unit tests again with Assertions turned off before I check my code in, but that may be overkill. – MiguelMunoz Oct 24 '19 at 23:22
-
2Assertions are disabled by default because prior to Java 1.4 it was perfectly legal to use the word “assert” for naming variables, methods, etc. This potentially creates a naming clash when using an older code with newer JVM versions. Therefore, for backward compatibility, the JVM disables assertion validation by default. – Michaël Benjamin Saerens Jun 18 '20 at 09:11
-
In case you are searching for `@Nullable` annotations, see https://stackoverflow.com/a/76999389/873282 for a sketch - and https://stackoverflow.com/q/4963300/873282 for a general discussion. – koppor Aug 29 '23 at 18:18
20 Answers
Assertions (by way of the assert
keyword) were added in Java 1.4. They are used to verify the correctness of an invariant in the code. They should never be triggered in production code, and are indicative of a bug or misuse of a code path. They can be activated at run-time by way of the -ea
option on the java
command, but are not turned on by default.
An example:
public Foo acquireFoo(int id) {
Foo result = (id > 50) ? fooService.read(id) : new Foo(id);
assert result != null;
return result;
}

- 3,119
- 19
- 19
- 37

- 9,775
- 2
- 29
- 27
-
88In fact, Oracle tells you not to use `assert` to check public method parameters (http://docs.oracle.com/javase/1.4.2/docs/guide/lang/assert.html). That should throw an `Exception` instead of killing the program. – SJuan76 Aug 25 '13 at 21:58
-
1Hey, your example proper makes an unobvious assumption. It assumes the contract of 'fooService.read(int)' is to never return null. – Opher Feb 28 '15 at 13:50
-
21But you still don't explain why they exist. Why can't you do an if() check and throw an exception? – El Mac Mar 04 '16 at 08:20
-
11@ElMac - assertions are for the dev/debug/test parts of the cycle - they are not for production. An if block runs in prod. Simple assertions won't break the bank, but expensive assertions that do complex data validation might bring down your production environment, which is why they are turned off there. – hoodaticus Mar 10 '16 at 19:24
-
2@hoodaticus you mean solely the fact that I can turn on/off all assertions for prod code is the reason? Because I can do complex data validation anyways and then handle it with exceptions. If I have production code, I could turn off the complex (and maybe expensive) assertions, because it should work and was tested already? In theory they shouldnt bring down the program because then you would have a problem anyways. – El Mac Mar 11 '16 at 06:57
-
12`This convention is unaffected by the addition of the assert construct. Do not use assertions to check the parameters of a public method. An assert is inappropriate because the method guarantees that it will always enforce the argument checks. It must check its arguments whether or not assertions are enabled. Further, the assert construct does not throw an exception of the specified type. It can throw only an AssertionError.` https://docs.oracle.com/javase/8/docs/technotes/guides/language/assert.html – Bakhshi Jul 26 '17 at 00:45
-
This answer needs to also explain what happens when assertion fails. Does it throw and exception? Does it abort the whole application? – Violet Giraffe Jul 19 '22 at 13:16
Let's assume that you are supposed to write a program to control a nuclear power-plant. It is pretty obvious that even the most minor mistake could have catastrophic results, therefore your code has to be bug-free (assuming that the JVM is bug-free for the sake of the argument).
Java is not a verifiable language, which means: you cannot calculate that the result of your operation will be perfect. The main reason for this are pointers: they can point anywhere or nowhere, therefore they cannot be calculated to be of this exact value, at least not within a reasonable span of code. Given this problem, there is no way to prove that your code is correct at a whole. But what you can do is to prove that you at least find every bug when it happens.
This idea is based on the Design-by-Contract (DbC) paradigm: you first define (with mathematical precision) what your method is supposed to do, and then verify this by testing it during actual execution. Example:
// Calculates the sum of a (int) + b (int) and returns the result (int).
int sum(int a, int b) {
return a + b;
}
While this is pretty obvious to work fine, most programmers will not see the hidden bug inside this one (hint: the Ariane V crashed because of a similar bug). Now DbC defines that you must always check the input and output of a function to verify that it worked correctly. Java can do this through assertions:
// Calculates the sum of a (int) + b (int) and returns the result (int).
int sum(int a, int b) {
assert (Integer.MAX_VALUE - a >= b) : "Value of " + a + " + " + b + " is too large to add.";
final int result = a + b;
assert (result - a == b) : "Sum of " + a + " + " + b + " returned wrong sum " + result;
return result;
}
Should this function now ever fail, you will notice it. You will know that there is a problem in your code, you know where it is and you know what caused it (similar to Exceptions). And what is even more important: you stop executing right when it happens to prevent any further code to work with wrong values and potentially cause damage to whatever it controls.
Java Exceptions are a similar concept, but they fail to verify everything. If you want even more checks (at the cost of execution speed) you need to use assertions. Doing so will bloat your code, but you can in the end deliver a product at a surprisingly short development time (the earlier you fix a bug, the lower the cost). And in addition: if there is any bug inside your code, you will detect it. There is no way of a bug slipping-through and cause issues later.
This still is not a guarantee for bug-free code, but it is much closer to that, than usual programs.

- 2,472
- 3
- 30
- 56

- 13,879
- 6
- 30
- 54
-
36I chose this example because it presents hidden bugs in seemingly bug-free code very well . If this is similar to what someone else presented, then they maybe had the same idea in mind. ;) – TwoThe Nov 04 '13 at 10:58
-
2I still don't understand why choose to use `assert` instead of just some `if` conditions? And to trigger these `assert`s you have to hit those edge cases while testing, which doesn't always happen. So what happens in production environments where `assert` is ignored? – Tony Chan Dec 19 '13 at 00:16
-
10You choose assert because it fails when the assertion is false. An if can have any behaviour. Hitting fringe cases is the job of Unit Testing. Using Design by Contract specified the contract rather well but as with real life contracts, you need a control to be sure they are respected. With assertions a watchdog is inserted that will then you when the contract is disrespected. Think of it as a nagging lawyer screaming "WRONG" every time you do something that is outside or against a contract you signed and then send you home so you can't continue to work and breach the contract further! – Eric Tobias Dec 19 '13 at 11:12
-
1The benefit of assert vs if is that you can specify a condition at runtime, that causes the JVM to completely ignore all assert statements as if they didn't exist, for an obvious performance gain. This is especially helpful if your asserts do some heavy calculation to determine their true/false state. You should however not disable asserts because they fail. In this case you should fix the code! – TwoThe Dec 19 '13 at 20:59
-
1@TwoThe outside the topic of assertion, is the second assert really necessary? Haha I cant think of a scenario where it would return the wrong result. – jantristanmilan Dec 21 '13 at 15:31
-
5Necessary in this simple case: no, but the DbC defines that __every__ result must be checked. Imagine someone now modifies that function to something much more complex, then he has to adapt the post-check as well, and then it suddenly becomes useful. – TwoThe Dec 23 '13 at 12:24
-
4Sorry to resurrect this, but I have a specific question. What is the difference between what @TwoThe did and instead of using assert just throwing a `new IllegalArgumentException` with the message? I mean, aside from having o add `throws` to the method declaration and the code to manage that exception somewhere else. Why `assert` insetad of throwing new Exception? Or why not an `if` instead of `assert`? Can't really get this :( – Blueriver Apr 13 '14 at 23:48
-
2There could be a `try {} catch (Throwable t)` somewhere in the code that would hide such exceptions. And you could do `if (...)` (in some languages assertions are even coded like that), but what do you do in the error case? Either your if would just duplicate what assertions are doing, or you would lower the effect of them. One purpose of assertions is that they poke you in the eye and scream "FIX ME!!" until you do it. Assert vs laziness so to say. – TwoThe Apr 14 '14 at 09:04
-
23-1: The assertion to check for overflow is wrong if `a` can be negative. The second assertion is useless; for int values, it is always the case that a + b - b == a. That test can only fail if the computer is fundamentally broken. To defend against that contingency, you need to check for consistency across multiple CPUs. – kevin cline Jul 29 '14 at 21:09
-
Interesting comments, but I'm curious where this comment that "Java isn't verifiable" comes from, or why you think so? You speak about pointers, and where they are pointing, but if there's a problem, then wouldn't code break all of the time? – XaolingBao May 20 '16 at 21:58
-
2Verifiable with mathematic precision would be more accurate. There is a whole area in computer science that tries to figure out how you can not only assume but (at compile-time) proof that you program is doing what it should be doing (see Ada Spark for example). This is easy to do for small pieces of code with limited reach, but as soon as you introduce global variables, or worse: global variables that not only hold one value but point to an object with many values, or even worse several other pointers as well, the whole construct gets so complicated, that the task becomes unmanageable. – TwoThe May 22 '16 at 07:31
-
1"And what is even more important: you stop executing right when it happens to prevent any further code to work with wrong values" -- except that assertions are disabled by default. I really wish they'd made a different decision there. – Aleksandr Dubinsky Jun 03 '16 at 03:26
-
1
-
Great answer, but not relevant to the 'assert' keyword? Asserts can be turned off, so any DbC code using it is fruitless. DbC requires actual run-time code. – Josef.B May 29 '18 at 12:34
-
Can be turned off doesn't mean they are by default. Turning them off is a performance feature you can use if you are certain that your code runs fine, otherwise they will be checked. – TwoThe May 30 '18 at 08:41
-
@Blueriver @Tony Chan The difference between using an assert and throwing an `IllegalArgumentException` is that the assertion will most likely be off in production. The whole point of assertions is that you can leave them off once you're confident in your code. Assertions are strictly a development-phase tool. They help you catch bugs earlier in the development cycle. – MiguelMunoz Oct 24 '19 at 23:41
-
-
1@Ashutosh Against all odds: yes, and you should do that. Many people disable those in production and with that their best chance to find bugs. Now of course your program should be hardened enough so that a single AssertionException does not lead to a total crash of the system, but to a way of informing the devs about the error followed by a proper recovery. – TwoThe Mar 02 '21 at 12:38
-
1[Oracle guide](https://docs.oracle.com/javase/7/docs/technotes/guides/language/assert.html#usage) states that assertions should _not_ be used for checking contracts! _"Argument checking is typically part of the published specifications (or contract) of a method, and these specifications must be obeyed whether assertions are enabled or disabled"_ (and, as @AleksandrDubinsky noted, **assertions are disabled by default!**) – Ilya Serbis Jul 20 '21 at 14:04
Assertions are a development-phase tool to catch bugs in your code. They're designed to be easily removed, so they won't exist in production code. So assertions are not part of the "solution" that you deliver to the customer. They're internal checks to make sure that the assumptions you're making are correct. The most common example is to test for null. Many methods are written like this:
void doSomething(Widget widget) {
if (widget != null) {
widget.someMethod(); // ...
... // do more stuff with this widget
}
}
Very often in a method like this, the widget should simply never be null. So if it's null, there's a bug in your code somewhere that you need to track down. But the code above will never tell you this. So in a well-intentioned effort to write "safe" code, you're also hiding a bug. It's much better to write code like this:
/**
* @param Widget widget Should never be null
*/
void doSomething(Widget widget) {
assert widget != null;
widget.someMethod(); // ...
... // do more stuff with this widget
}
This way, you will be sure to catch this bug early. (It's also useful to specify in the contract that this parameter should never be null.) Be sure to turn assertions on when you test your code during development. (And persuading your colleagues to do this, too is often difficult, which I find very annoying.)
Now, some of your colleagues will object to this code, arguing that you should still put in the null check to prevent an exception in production. In that case, the assertion is still useful. You can write it like this:
void doSomething(Widget widget) {
assert widget != null;
if (widget != null) {
widget.someMethod(); // ...
... // do more stuff with this widget
}
}
This way, your colleagues will be happy that the null check is there for production code, but during development, you're no longer hiding the bug when widget is null.
Here's a real-world example: I once wrote a method that compared two arbitrary values for equality, where either value could be null:
/**
* Compare two values using equals(), after checking for null.
* @param thisValue (may be null)
* @param otherValue (may be null)
* @return True if they are both null or if equals() returns true
*/
public static boolean compare(final Object thisValue, final Object otherValue) {
boolean result;
if (thisValue == null) {
result = otherValue == null;
} else {
result = thisValue.equals(otherValue);
}
return result;
}
This code delegates the work of the equals()
method in the case where thisValue is not null. But it assumes the equals()
method correctly fulfills the contract of equals()
by properly handling a null parameter.
A colleague objected to my code, telling me that many of our classes have buggy equals()
methods that don't test for null, so I should put that check into this method. It's debatable if this is wise, or if we should force the error, so we can spot it and fix it, but I deferred to my colleague and put in a null check, which I've marked with a comment:
public static boolean compare(final Object thisValue, final Object otherValue) {
boolean result;
if (thisValue == null) {
result = otherValue == null;
} else {
result = otherValue != null && thisValue.equals(otherValue); // questionable null check
}
return result;
}
The additional check here, other != null
, is only necessary if the equals()
method fails to check for null as required by its contract.
Rather than engage in a fruitless debate with my colleague about the wisdom of letting the buggy code stay in our code base, I simply put two assertions in the code. These assertions will let me know, during the development phase, if one of our classes fails to implement equals()
properly, so I can fix it:
public static boolean compare(final Object thisValue, final Object otherValue) {
boolean result;
if (thisValue == null) {
result = otherValue == null;
assert otherValue == null || otherValue.equals(null) == false;
} else {
result = otherValue != null && thisValue.equals(otherValue);
assert thisValue.equals(null) == false;
}
return result;
}
The important points to keep in mind are these:
Assertions are development-phase tools only.
The point of an assertion is to let you know if there's a bug, not just in your code, but in your code base. (The assertions here will actually flag bugs in other classes.)
Even if my colleague was confident that our classes were properly written, the assertions here would still be useful. New classes will be added that might fail to test for null, and this method can flag those bugs for us.
In development, you should always turn assertions on, even if the code you've written doesn't use assertions. My IDE is set to always do this by default for any new executable.
The assertions don't change the behavior of the code in production, so my colleague is happy that the null check is there, and that this method will execute properly even if the
equals()
method is buggy. I'm happy because I will catch any buggyequals()
method in development.
Also, you should test your assertion policy by putting in a temporary assertion that will fail, so you can be certain that you are notified, either through the log file or a stack trace in the output stream.

- 4,548
- 3
- 34
- 51
-
Good points about "hiding a bug" and how asserts expose bugs during development! – Brent Bradburn Aug 02 '18 at 20:58
-
None of these checks are slow, so there is no reason to turn them off in production. They should be converted into logging statements, so that you could detect problems that don't show up in your "development phase." (Really, there is no such thing as a development phase, anyway. Development ends when you decide to stop maintaining your code at all.) – Aleksandr Dubinsky Oct 30 '19 at 10:52
When should Assert be used?
A lot of good answers explaining what the assert
keyword does, but few answering the real question, "when should the assert
keyword be used in real life?" The answer:
Almost never
Assertions, as a concept, are wonderful. Good code has lots of if (...) throw ...
statements (and their relatives like Objects.requireNonNull
and Math.addExact
). However, certain design decisions have greatly limited the utility of the assert
keyword itself.
The driving idea behind the assert
keyword is premature optimization, and the main feature is being able to easily turn off all checks. In fact, the assert
checks are turned off by default.
However, it is critically important that invariant checks continue to be done in production. This is because perfect test coverage is impossible, and all production code will have bugs which assertions should help to diagnose and mitigate.
Therefore, the use of if (...) throw ...
should be preferred, just as it is required for checking parameter values of public methods and for throwing IllegalArgumentException
.
Occasionally, one might be tempted to write an invariant check that does take an undesirably long time to process (and is called often enough for it to matter). However, such checks will slow down testing which is also undesirable. Such time-consuming checks are usually written as unit tests. Nevertheless, it may sometimes make sense to use assert
for this reason.
Do not use assert
simply because it is cleaner and prettier than if (...) throw ...
(and I say that with great pain, because I like clean and pretty). If you just cannot help yourself, and can control how your application is launched, then feel free to use assert
but always enable assertions in production. Admittedly, this is what I tend to do. I am pushing for a lombok annotation that will cause assert
to act more like if (...) throw ...
. Vote for it here.
(Rant: the JVM devs were a bunch of awful, prematurely optimizing coders. That is why you hear about so many security issues in the Java plugin and JVM. They refused to include basic checks and assertions in production code, and we are continuing to pay the price.)

- 22,436
- 15
- 82
- 99
-
Spot on. But it is actually worse than that because it throws an AssertionError instead of an Exception that might be trapped, logged, recovered etc. by higher level code. (Think of a web app that has a bug.) – Tuntable Jun 16 '16 at 08:31
-
2@aberglas A catch-all clause is `catch (Throwable t)`. There is no reason to not try to trap, log, or retry/recover from OutOfMemoryError, AssertionError, etc. – Aleksandr Dubinsky Jun 16 '16 at 21:39
-
@AleksandrDubinsky The reality is that the common practice (I am not saying it is the right one) is to use catch (Exception e) as a catch-all statement, that is what is commonly found. Assertions wouldn't get caught by that, I think that is what aberglas is talking about – raspacorp Jul 05 '16 at 21:14
-
1
-
1I don't agree. Many of my assertions are used to make sure my API is getting called correctly. For example, I might write a private method that should only be called when an object holds a lock. If another developer calls that method from part of the code that doesn't lock the object, the assertion will tell them right away that they made a mistake. There are a lot of mistakes like this that can, with certainty, get caught in the development phase, and assertions are very useful in these cases. – MiguelMunoz Aug 23 '16 at 02:55
-
3@MiguelMunoz In my answer I said that the idea of assertions is very good. It is the implementation of the `assert` keyword is bad. I will edit my answer to make it more clear that I am referring to the keyword, not the concept. – Aleksandr Dubinsky Aug 23 '16 at 08:47
-
2I like the fact that it throws an AssertionError instead of an Exception. Too many developers still haven't learned that they shouldn't catch Exception if the code can only throw something like IOException. I've had bugs in my code get completely swallowed because somebody caught Exception. Assertions don't get caught in this trap. Exceptions are for situations that you expect to see in production code. As for logging, you should be logging all your errors too, even though errors are rare. For example, do you really want to let an OutOfMemoryError pass without logging it? – MiguelMunoz May 16 '17 at 01:25
-
2I strongly disagree. You want assertions to be something else, but there are already `Preconditions` and `Verify` in Guava and whatever. Assertions (as designed in Java) are sort of tests - not to be run in production. They're much cheaper to write than tests; they can't replace tests but they complement them nicely. They can check conditions which are too expensive to be checked in production. They must not be misused for preconditions. – maaartinus Oct 25 '19 at 13:48
-
@maaartinus What conditions are too expensive to check in production? Can you give examples what you use assertions for? – Aleksandr Dubinsky Oct 28 '19 at 15:40
-
@AleksandrDubinsky See [this comment](https://stackoverflow.com/questions/2758224/what-does-the-java-assert-keyword-do-and-when-should-it-be-used/37605954#comment103418410_44056242) and [my answer](https://stackoverflow.com/a/52918492/581205) for real world usage (not mine). In my code, there are things like `assert Sets.newHashSet(userIds).size() == userIds.size()` where I'm pretty sure that the list I just created has unique elements, but I wanted to document and double check it (I really need a list here, no set; the check here is rather cheap, but also rather superfluous). – maaartinus Oct 29 '19 at 22:01
-
@maaartinus The example of Excel does give food for thought. However, your check for user id uniqueness should probably be enabled in production code. – Aleksandr Dubinsky Oct 30 '19 at 10:43
Here's the most common use case. Suppose you're switching on an enum value:
switch (fruit) {
case apple:
// do something
break;
case pear:
// do something
break;
case banana:
// do something
break;
}
As long as you handle every case, you're fine. But someday, somebody will add fig to your enum and forget to add it to your switch statement. This produces a bug that may get tricky to catch, because the effects won't be felt until after you've left the switch statement. But if you write your switch like this, you can catch it immediately:
switch (fruit) {
case apple:
// do something
break;
case pear:
// do something
break;
case banana:
// do something
break;
default:
assert false : "Missing enum value: " + fruit;
}

- 4,548
- 3
- 34
- 51
-
4That's why you should have warnings enabled and warnings treated as errors. Any halfway decent compiler is capable of telling you, if only you allow it to tell you, that you are missing an enum check, and it will do so at compile time, which is unspeakably better than (perhaps, one day) finding out at run time. – Mike Nakis Sep 23 '14 at 15:43
-
12why use an assertion here rather than an exception of some sort, e.g., an illegalargumentexception? – liltitus27 Jun 03 '15 at 19:37
-
9This will throw an `AssertionError` if assertions are enabled (`-ea`). What is the desired behavior in production? A silent no-op and potential disaster later in the execution? Probably not. I would suggest an explicit `throw new AssertionError("Missing enum value: " + fruit);`. – aioobe Mar 10 '16 at 16:28
-
2There's a good argument to be made for just throwing an AssertionError. As for the proper behavior in production, the whole point of assertions is to keep this from happening in production. Assertions are a development phase tool to catch bugs, which can easily be removed from production code. In this case, there's no reason to remove it from production code. But in many cases, integrity tests may slow things down. By putting these test inside assertions, which aren't used in production code, you are free to write thorough tests, without worrying that they will slow down your production code. – MiguelMunoz May 12 '16 at 22:30
-
This seems to be wrong. IMHO you should not use `default` so that the compiler can warn you on missing cases. You can `return` instead of `break` (this may need extracting the method) and then handle the missing case after the switch. This way you get both the warning and an opportunity to `assert`. – maaartinus Oct 25 '19 at 13:51
Assertions are used to check post-conditions and "should never fail" pre-conditions. Correct code should never fail an assertion; when they trigger, they should indicate a bug (hopefully at a place that is close to where the actual locus of the problem is).
An example of an assertion might be to check that a particular group of methods is called in the right order (e.g., that hasNext()
is called before next()
in an Iterator
).

- 133,037
- 18
- 149
- 215
-
1
-
6@DJClayworth: You don't need to avoid triggering assertions either. :-) – Donal Fellows May 03 '10 at 16:52
What does the assert keyword in Java do?
Let's look at the compiled bytecode.
We will conclude that:
public class Assert {
public static void main(String[] args) {
assert System.currentTimeMillis() == 0L;
}
}
generates almost the exact same bytecode as:
public class Assert {
static final boolean $assertionsDisabled =
!Assert.class.desiredAssertionStatus();
public static void main(String[] args) {
if (!$assertionsDisabled) {
if (System.currentTimeMillis() != 0L) {
throw new AssertionError();
}
}
}
}
where Assert.class.desiredAssertionStatus()
is true
when -ea
is passed on the command line, and false otherwise.
We use System.currentTimeMillis()
to ensure that it won't get optimized away (assert true;
did).
The synthetic field is generated so that Java only needs to call Assert.class.desiredAssertionStatus()
once at load time, and it then caches the result there. See also: What is the meaning of "static synthetic"?
We can verify that with:
javac Assert.java
javap -c -constants -private -verbose Assert.class
With Oracle JDK 1.8.0_45, a synthetic static field was generated (see also: What is the meaning of "static synthetic"?):
static final boolean $assertionsDisabled;
descriptor: Z
flags: ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
together with a static initializer:
0: ldc #6 // class Assert
2: invokevirtual #7 // Method java/lang Class.desiredAssertionStatus:()Z
5: ifne 12
8: iconst_1
9: goto 13
12: iconst_0
13: putstatic #2 // Field $assertionsDisabled:Z
16: return
and the main method is:
0: getstatic #2 // Field $assertionsDisabled:Z
3: ifne 22
6: invokestatic #3 // Method java/lang/System.currentTimeMillis:()J
9: lconst_0
10: lcmp
11: ifeq 22
14: new #4 // class java/lang/AssertionError
17: dup
18: invokespecial #5 // Method java/lang/AssertionError."<init>":()V
21: athrow
22: return
We conclude that:
- there is no bytecode level support for
assert
: it is a Java language concept assert
could be emulated pretty well with system properties-Pcom.me.assert=true
to replace-ea
on the command line, and athrow new AssertionError()
.

- 1
- 1

- 347,512
- 102
- 1,199
- 985
-
2So the `catch (Throwable t)` clause is able to catch assertion violations too? For me that limits their utility just to the case where the body of the assertion is time-consuming, which is rare. – Evgeni Sergeev Nov 15 '15 at 06:34
-
2I'm not sure why it limits the assertion's usefulness. You shouldn't ever catch a Throwable except in very rare cases. If you do need to catch Throwable but want it to not catch assertions, you can just catch the `AssertionError` first and rethrow it. – MiguelMunoz Aug 13 '16 at 10:21
An assertion allows for detecting defects in the code. You can turn on assertions for testing and debugging while leaving them off when your program is in production.
Why assert something when you know it is true? It is only true when everything is working properly. If the program has a defect, it might not actually be true. Detecting this earlier in the process lets you know something is wrong.
An assert
statement contains this statement along with an optional String
message.
The syntax for an assert statement has two forms:
assert boolean_expression;
assert boolean_expression: error_message;
Here are some basic rules which govern where assertions should be used and where they should not be used. Assertions should be used for:
Validating input parameters of a private method. NOT for public methods.
public
methods should throw regular exceptions when passed bad parameters.Anywhere in the program to ensure the validity of a fact which is almost certainly true.
For example, if you are sure that it will only be either 1 or 2, you can use an assertion like this:
...
if (i == 1) {
...
}
else if (i == 2) {
...
} else {
assert false : "cannot happen. i is " + i;
}
...
- Validating post conditions at the end of any method. This means, after executing the business logic, you can use assertions to ensure that the internal state of your variables or results is consistent with what you expect. For example, a method that opens a socket or a file can use an assertion at the end to ensure that the socket or the file is indeed opened.
Assertions should not be used for:
Validating input parameters of a public method. Since assertions may not always be executed, the regular exception mechanism should be used.
Validating constraints on something that is input by the user. Same as above.
Should not be used for side effects.
For example this is not a proper use because here the assertion is used for its side effect of calling of the doSomething()
method.
public boolean doSomething() {
...
}
public void someMethod() {
assert doSomething();
}
The only case where this could be justified is when you are trying to find out whether or not assertions are enabled in your code:
boolean enabled = false;
assert enabled = true;
if (enabled) {
System.out.println("Assertions are enabled");
} else {
System.out.println("Assertions are disabled");
}

- 5,292
- 5
- 33
- 54

- 1,804
- 3
- 19
- 30
A real world example, from a Stack-class (from Assertion in Java Articles)
public int pop() {
// precondition
assert !isEmpty() : "Stack is empty";
return stack[--num];
}

- 22,894
- 45
- 188
- 319

- 29,019
- 9
- 65
- 81
-
85This would be frowned upon in C: An assertion is something that REALLY NEVER should happen - popping an empty stack should throw a NoElementsException or something along the lines. See Donal's reply. – Konerak May 03 '10 at 13:35
-
4I agree. Even though this is taken from an official tutorial, it's a bad example. – DJClayworth May 03 '10 at 16:48
-
4This should throw http://docs.oracle.com/javase/6/docs/api/java/util/NoSuchElementException.html as in http://docs.oracle.com/javase/6/docs/api/java/util/LinkedList.html#pop() – Aram Kocharyan Mar 25 '13 at 01:20
-
8There's probably a memory leak there. You should set stack[num] = null; in order for the GC to do its job properly. – H.Rabiee Apr 08 '14 at 20:26
-
3I think in a private method, it would be correct to use an assertion, as it would be weird to have exceptions for a malfunction of a class or method. In a public method, calling it from somewhere outside, you can't really tell how the other code uses it. Does it really check isEmpty() or not? You don't know. – Vlasec Aug 05 '14 at 11:41
-
an if-statement can emulate an assert as well, but what about vice-versa? If you used assert as an if-statement could you use it instead of if? – AMDG Sep 06 '14 at 22:49
-
2@Konerak Popping this stack should also "really never" happen if its contract forbids it. Exceptions need to have distinct names if you expect to catch and handle them. If an error such as popping this stack should be fixed in code instead of handled at runtime, then it's fine to make it raise an assertion. – Aleksandr Dubinsky Feb 07 '18 at 09:31
In addition to all the great answers provided here, the official Java SE 7 programming guide has a pretty concise manual on using assert
; with several spot-on examples of when it's a good (and, importantly, bad) idea to use assertions, and how it's different from throwing exceptions.

- 7,119
- 5
- 25
- 41

- 19,664
- 7
- 61
- 59
-
1I agree. The article has many excellent examples. I especially liked the one to make sure a method is only called when the object holds a lock. – MiguelMunoz Aug 23 '16 at 02:51
Assert is very useful when developing. You use it when something just cannot happen if your code is working correctly. It's easy to use, and can stay in the code for ever, because it will be turned off in real life.
If there is any chance that the condition can occur in real life, then you must handle it.
I love it, but don't know how to turn it on in Eclipse/Android/ADT . It seems to be off even when debugging. (There is a thread on this, but it refers to the 'Java vm', which does not appear in the ADT Run Configuration).

- 131
- 1
- 3
- 19
-
1To enable assertion in eclipse IDE, please follow http://tutoringcenter.cs.usfca.edu/resources/enabling-assertions-in-eclipse.html – Ayaz Pasha Jan 05 '19 at 05:27
-
I don't think there's a way to turn on asserts in Android. This is very disappointing. – MiguelMunoz Oct 24 '19 at 20:20
Here's an assertion I wrote in a server for a Hibernate/SQL project. An entity bean had two effectively-boolean properties, called isActive and isDefault. Each could have a value of "Y" or "N" or null, which was treated as "N". We want to make sure the browser client is limited to these three values. So, in my setters for these two properties, I added this assertion:
assert new HashSet<String>(Arrays.asList("Y", "N", null)).contains(value) : value;
Notice the following.
This assertion is for the development phase only. If the client sends a bad value, we will catch that early and fix it, long before we reach production. Assertions are for defects that you can catch early.
This assertion is slow and inefficient. That's okay. Assertions are free to be slow. We don't care because they're development-only tools. This won't slow down the production code because assertions will be disabled. (There's some disagreement on this point, which I'll get to later.) This leads to my next point.
This assertion has no side effects. I could have tested my value against an unmodifiable static final Set, but that set would have stayed around in production, where it would never get used.
This assertion exists to verify the proper operation of the client. So by the time we reach production, we will be sure that the client is operating properly, so we can safely turn the assertion off.
Some people ask this: If the assertion isn't needed in production, why not just take them out when you're done? Because you'll still need them when you start working on the next version.
Some people have argued that you should never use assertions, because you can never be sure that all the bugs are gone, so you need to keep them around even in production. And so there's no point in using the assert statement, since the only advantage to asserts is that you can turn them off. Hence, according to this thinking, you should (almost) never use asserts. I disagree. It's certainly true that if a test belongs in production, you should not use an assert. But this test does not belong in production. This one is for catching a bug that's not likely to ever reach production, so it may safely be turned off when you're done.
BTW, I could have written it like this:
assert value == null || value.equals("Y") || value.equals("N") : value;
This is fine for only three values, but if the number of possible values gets bigger, the HashSet version becomes more convenient. I chose the HashSet version to make my point about efficiency.

- 4,548
- 3
- 34
- 51
-
I strongly doubt that using such a *tiny* a `HashSet` brings any speed advantage over an `ArrayList`. Moreover, the set and list creations dominate the lookup time. They'd fine when using a constant. That all said, +1. – maaartinus Oct 21 '18 at 18:01
-
All true. I did it this inefficient way to illustrate my point that assertions are free to be slow. This one could be made more efficient, but there are others that can't. In an excellent book called "Writing Solid Code," Steve Maguire tells of an assertion in Microsoft Excel to test the new incremental-update code that skipped cells that shouldn't change. Every time the user made a change, the assertion would recalculate the entire spreadsheet to make sure the results matched those by the incremental-update feature. It really slowed the debug version, but they caught all their bugs early. – MiguelMunoz Oct 24 '19 at 20:32
-
Fully agreed. Assertions are sort of tests - they're less versatile than ordinary tests, but they can cover private methods and they're much cheaper to write. I'll try to use them even more. – maaartinus Oct 25 '19 at 12:41
Assertions are checks which may get switched off. They're rarely used. Why?
- They must not be used for checking public method arguments as you have no control over them.
- They should not be used for simple checks like
result != null
as such checks are very fast and there's hardly anything to save.
So, what's left? Expensive checks for conditions really expected to be true. A good example would be the invariants of a data structure like RB-tree. Actually, in ConcurrentHashMap
of JDK8, there are a few such meaningful asserts for the TreeNodes
.
- You really don't want to switch them on in production as they could easily dominate the run time.
- You may want to switch them on or off during tests.
- You definitely want to switch them on when working on the code.
Sometimes, the check is not really expensive, but at the same time, you're pretty sure, it'll pass. In my code, there's e.g.,
assert Sets.newHashSet(userIds).size() == userIds.size();
where I'm pretty sure that the list I just created has unique elements, but I wanted to document and double check it.

- 44,714
- 32
- 161
- 320
To recap (and this is true of many languages not just Java):
"assert" is primarily used as a debugging aid by software developers during the debugging process. Assert-messages should never appear. Many languages provide a compile-time option that will cause all "asserts" to be ignored, for use in generating "production" code.
"exceptions" are a handy way to handle all kinds of error conditions, whether or not they represent logic errors, because, if you run into an error-condition such that you cannot continue, you can simply "throw them up into the air," from wherever you are, expecting someone else out there to be ready to "catch" them. Control is transferred in one step, straight from the code that threw the exception, straight to the catcher's mitt. (And the catcher can see the complete backtrace of calls that had taken place.)
Furthermore, callers of that subroutine don't have to check to see if the subroutine succeeded: "if we're here now, it must have succeeded, because otherwise it would have thrown an exception and we wouldn't be here now!" This simple strategy makes code-design and debugging much, much easier.
Exceptions conveniently allow fatal-error conditions to be what they are: "exceptions to the rule." And, for them to be handled by a code-path that is also "an exception to the rule ... "fly ball!"

- 8,490
- 5
- 28
- 41
Here's another example. I wrote a method that finds the median of the values in two sorted arrays. The method assumes the arrays are already sorted. For performance reasons, it should NOT sort the arrays first, or even check to ensure they're sorted. However, it's a serious bug to call this method with unsorted data, and we want those bugs to get caught early, in the development phase. So here's how I handled those seemingly conflicting goals:
public static int medianOf(int[] a, int[] b) {
assert assertionOnlyIsSorted(a); // Assertion is order n
assert assertionOnlyIsSorted(b);
... // rest of implementation goes here. Algorithm is order log(n)
}
public static boolean assertionOnlyIsSorted(int[] array) {
for (int i=1; i<array.length; ++i) {
if (array[i] < array[i-1]) {
return false;
}
return true;
}
}
This way, the test, which is slow, is only performed during the development phase, where speed is less important than catching bugs. You want the medianOf()
method to have log(n) performance, but the "is sorted" test is order n. So I put it inside an assertion, to limit its use to the development phase, and I give it a name that makes it clear it's not suitable for production.
This way I have the best of both worlds. In development, I know that any method that calls this incorrectly will get caught and fixed. And I know that the slow test to do so won't affect performance in production. (It's also a good illustration of why you want to leave assertions off in production, but turn them on in development.)

- 4,548
- 3
- 34
- 51
Assertion are basically used to debug the application or it is used in replacement of exception handling for some application to check the validity of an application.
Assertion works at run time. A simple example, that can explain the whole concept very simply, is herein - What does the assert keyword do in Java? (WikiAnswers).

- 30,738
- 21
- 105
- 131

- 709
- 5
- 8
Assertions are disabled by default. To enable them we must run the program with -ea
options (granularity can be varied). For example, java -ea AssertionsDemo
.
There are two formats for using assertions:
- Simple: eg.
assert 1==2; // This will raise an AssertionError
. - Better:
assert 1==2: "no way.. 1 is not equal to 2";
This will raise an AssertionError with the message given displayed too and is thus better. Although the actual syntax isassert expr1:expr2
where expr2 can be any expression returning a value, I have used it more often just to print a message.

- 30,738
- 21
- 105
- 131

- 2,283
- 1
- 17
- 16
I don’t know what the history is behind this feature in Java. But I have an idea about what assert
can be used for that I don’t think has been brought up in this thread.
Say you have an enum which you switch on:(†)
public enum Veggie {
CAULIFLOWER,
CARROT,
}
// Another class
switch (veggie) {
case CAULIFLOWER: value = 5;
case CARROT: value = 3;
}
†: Maybe good Java compilers/tooling will catch missing enum values statically. In that case just imagine that you find some bug and you fix it. Then you can add a regression test in the code proper using the technique described below.
There’s no good default case for this. So you really want to make sure that you cover all values. You want to make sure that you update the switch block whenever you add a new enum variant:
public enum Veggie {
CAULIFLOWER,
CARROT,
TOMATO,
}
But it turns out that this code is called right when the user loads a particular view in your web application. And the view can persist in spite of this error: it would be a bug but it’s not worth interfering with the loading of the view (let’s say that the user is just presented with a few wrong numbers). So you just log a warning:
switch (veggie) {
case CAULIFLOWER: value = 5;
case CARROT: value = 3;
default: nonExhaustiveMatchOnEnum();
// […]
public static void nonExhaustiveMatchOnEnum() {
String errorMessage: "Missing veggie";
logger.warn(errorMessage);
}
But you do want this fail immediately when you are developing the code—you the developer can fix such a bug in five minutes, unlike the users of your web application.
So you can just add an assert false
:
public static void nonExhaustiveMatchOnEnum() {
String errorMessage: "Missing veggie";
assert false : errorMessage;
logger.warn(errorMessage);
}
Now the app will crash locally but only log a warning on production (assuming you use java -ea
locally but not in production).

- 2,179
- 1
- 17
- 39
Basically, "assert true" will pass and "assert false" will fail. Let's looks at how this will work:
public static void main(String[] args)
{
String s1 = "Hello";
assert checkInteger(s1);
}
private static boolean checkInteger(String s)
{
try {
Integer.parseInt(s);
return true;
}
catch(Exception e)
{
return false;
}
}

- 30,738
- 21
- 105
- 131
assert
is a keyword. It was introduced in JDK 1.4. The are two types of assert
s
- Very simple
assert
statements - Simple
assert
statements.
By default all assert
statements will not be executed. If an assert
statement receives false, then it will automatically raise an assertion error.

- 9,365
- 7
- 41
- 55

- 11
- 1
-
1It doesn't provide any real life example, which is the aim of the question – rubenafo Mar 02 '17 at 10:39
-
2Did you just copy paste from: https://www.amazon.com/Programmer-Study-1Z0-803-1Z0-804-Certification/dp/0071772006 ? – Koray Tugay Jun 23 '17 at 13:28