Dashboard > JJGuidelines > Home > Appendix B - Guidelines Rules > B.5. Assertions rules
JJGuidelines Log In | Sign Up   View a printable version of the current page.
B.5. Assertions rules
Added by Alexander Bollaert, last edited by Alexander Bollaert on Jan 15, 2007  (view change)

Assertions rules

Overview

Table B.5. Assertions rules

ASSERT_001: Check A Method's Arguments
ASSERT_002: Do Not Use Assertions For Argument Checking In A public Method
ASSERT_003: Do Not Do Any Processing In An Assertion's Condition
ASSERT_004: Do Not Catch Assertion Related Exceptions
ASSERT_005: Use Assertions In A switch Statement's default Case Correct
ASSERT_006: Do Not Evaluate More Than One Condition In An Assertion
ASSERT_007: Make An Assertion Descriptive

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) {
	// Enforce specified precondition in public method
	assert count <= 0 : "Illegal initial count: " + count;
	initialCount = count;
}

RIGHT

public void setInitialCount(int count) {
	// Enforce specified precondition in public method
	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

//  the item will not be removed if assertions are disabled! 
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) {
	        // some error handling
	}
}

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";
}

Site powered by a free Open Source Project / Non-profit License (more) of Confluence - the Enterprise wiki.
Learn more or evaluate Confluence for your organisation.
Hosted by JavaLobby
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.2.5 Build:#520 Jun 27, 2006) - Bug/feature request - Contact Administrators