Assertions rules
Overview
Table B.5. Assertions rules
ASSERT_001: Check A Method's Arguments
Always check argument values in accessible (public, protected and package local) methods.
WRONG
public void setName(String name) {
this.name = name.trim();
}
RIGHT
public void setName(String name) {
if (name == null) {
throw new IllegalArgumentException("name can not be null");
}
this.name = name.trim();
}
ASSERT_002: Do Not Use Assertions For Argument Checking In A public Method
By convention, preconditions on methods that are public, protected or package local are enforced by explicit checks that throw particular, specified exceptions (a commonly used exception is java.lang.IllegalArgumentException). We can't use assertions for this because the method must guarantee that these checks will ALWAYS be done, even if assertions are disabled.
WRONG
public void setInitialCount(int count) {
assert count <= 0 : "Illegal initial count: " + count;
initialCount = count;
}
RIGHT
public void setInitialCount(int count) {
if (count <= 0) {
throw new IllegalArgumentException("Initial count must be > 0, got " + count);
}
initialCount = count;
}
 | Remember to throw a specific exception if the method's scope changes. |
ASSERT_003: Do Not Do Any Processing In An Assertion's Condition
When assertions are disabled they are not executed by the JVM. This means that the condition, stated in the assertion, will not be evaluated and any processing done in the condition will not be executed.
WRONG
assert set.remove(item) : "The item was not in the set.";
RIGHT
boolean modified = set.remove(item);
assert modified : "The item was not in the set.";
ASSERT_004: Do Not Catch Assertion Related Exceptions
Don't catch any assertion related exceptions. Catching these exceptions bypasses the whole assertion and Design By Contract mechanism. Exceptions include:
- AssertError
- IllegalArgumentException
- Your own assertion failed exception in case you are using your own assertion implementation.
WRONG
public void setData() {
try {
setName(null);
} catch (IllegalArgumentException e) {
}
}
public void setName(String name) {
if (name == null) {
throw new IllegalArgumentException("name can not be null");
}
this.name = name;
}
RIGHT
Don't catch the IllegalArgumentException.
ASSERT_005: Use Assertions In A switch Statement's default Case Correct
switch statements with no default case could use assertions to ensure that only known cases are handled. The way in which the assertion failure is reported to the outside world depends on the scope of the method in which the statement is used and the type of value that is evaluated by the switch statement.
Table B.6. What Kind Of Assertion To Use
| Use |
When |
| assert statement |
- If the method containing the switch statement is private
- If the value evaluated in the switch statement is a class variable
|
| IllegalArgumentException |
- If the value evaluated in the switch statement is a value that was provided as an argument to the non-private method containing the switch statement
|
RIGHT
Using IllegalArgumentException
public String getDescription(int code) {
switch (code) {
case NAME:
description = "name";
break;
case ADDRESS:
description = "address";
break;
default:
throw new IllegalArgumentException("Unexpected code " + code);
}
assert (description != null) : "Expected a description";
return description;
}
Using assert
public String getDescription() {
switch (this.code) {
case NAME:
description = "name";
break;
case ADDRESS:
description = "address";
break;
default:
assert false : "Unknown code " + code;
}
assert (description != null) : "Expected a description";
return description;
}
ASSERT_006: Do Not Evaluate More Than One Condition In An Assertion
Evaluate only one condition in a an assertion (or assertion like) expression. If you evaluate more than one condition you don't know which specific assumption is invalid and you will not be able to provide sufficient feedback.
WRONG
public void setName(String first, String last) {
if ((first == null) || (last == null)) {
throw new IllegalArgumentException("first or last can not be null");
}
}
private void setName(String first, String last) {
assert (first != null) && (last != null) : "first or last can not be null";
}
RIGHT
public void setName(String first, String last) {
if (first == null) {
throw new IllegalArgumentException("first can not be null");
}
if (last == null) {
throw new IllegalArgumentException("last can not be null");
}
}
private void setName(String first, String last) {
assert (first != null) : "first can not be null";
assert (last != null) : "last can not be null";
}
ASSERT_007: Make An Assertion Descriptive
Make your assertions descriptive by adding a message stating the assumption you are making. If the assertion then fails the description can be presented is to the user. If no description is provided to only signal you get is that something went wrong.
WRONG
public void setName(String name) {
if (name == null) {
throw new IllegalArgumentException();
}
}
private void setName(String name) {
assert (name != null);
}
RIGHT
public void setName(String name) {
if (name == null) {
throw new IllegalArgumentException("name can not be null");
}
}
private void setName(String name) {
assert (name != null) : "name can not be null";
}