There are some patterns for checking whether a parameter to a method has been given a null
value.
First, the classic one. It is common in self-made code
There is no vote for this one, but I use a slight variation of #2, like
erStr += nullCheck (varName, String errMsg); // returns formatted error message
Rationale: (1) I can loop over a bunch of arguments, (2) The nullCheck method is tucked away in a superclass and (3) at the end of the loop,
if (erStr.length() > 0)
// Send out complete error message to client
else
// do stuff with variables
In the superclass method, your #3 looks nice, but I wouldn't throw an exception (what is the point, somebody has to handle it, and as a servlet container, tomcat will ignore it, so it might as well be this()) Regards, - M.S.
You should not be throwing NullPointerException. If you want a NullPointerException, just dont check the value and it will be thrown automatically when the parameter is null and you attempt to dereference it.
Check out the apache commons lang Validate and StringUtils classes.
Validate.notNull(variable)
it will throw an IllegalArgumentException if "variable" is null.
Validate.notEmpty(variable)
will throw an IllegalArgumentException if "variable" is empty (null or zero length".
Perhaps even better:
String trimmedValue = StringUtils.trimToEmpty(variable)
will guarantee that "trimmedValue" is never null. If "variable" is null, "trimmedValue" will be the empty string ("").
You can use the Objects Utility Class.
public void method1(String arg) {
Objects.requireNonNull(arg);
}
see http://docs.oracle.com/javase/7/docs/api/java/util/Objects.html#requireNonNull%28T%29
I prefer method 4, 5 or 6, with #4 being applied to public API methods and 5 / 6 for internal methods, although #6 would be more frequently applied to public methods.
/**
* Method 4.
* @param arg A String that should have some method called upon it. Will be ignored if
* null, empty or whitespace only.
*/
public void method4(String arg) {
// commons stringutils
if (StringUtils.isNotBlank(arg) {
arg.trim();
}
}
/**
* Method 5.
* @param arg A String that should have some method called upon it. Shouldn't be null.
*/
public void method5(String arg) {
// Let NPE sort 'em out.
arg.trim();
}
/**
* Method 6.
* @param arg A String that should have some method called upon it. Shouldn't be null.
*/
public void method5(String arg) {
// use asserts, expect asserts to be enabled during dev-time, so that developers
// that refuse to read the documentations get slapped on the wrist for still passing
// null. Assert is a no-op if the -ae param is not passed to the jvm, so 0 overhead.
assert arg != null : "Arg cannot be null"; // insert insult here.
arg.trim();
}
The best solution to handle nulls is to not use nulls. Wrap third-party or library methods that may return nulls with null guards, replacing the value with something that makes sense (such as an empty string) but does nothing when used. Throw NPE's if a null really shouldn't be passed, especially in setter methods where the passed object doesn't get called right away.
I'd use the built-in Java assert mechanism.
assert arg != null;
The advantage of this over all the other methods is that it can be switched off.
Approach #3: arg.getClass();
is clever, but unless this idiom see widespread adoption, I'd prefer the clearer, more verbose methods as opposed to saving a few characters. I'm a "write once, read many" kind of programmer.
The other approaches are self-documenting: there's a log message you can use to clarify what happened - this log message is use when reading the code and also at run-time. arg.getClass()
, as it stands, is not self-documenting. You could use a comment at least o clarify to reviewers of the code:
arg.getClass(); // null check
But you still don't get a chance to put a specific message in the runtime like you can with the other methods.
Approach #1 vs #2 (null-check+NPE/IAE vs assert): I try to follow guidelines like this:
http://data.opengeo.org/GEOT-290810-1755-708.pdf
Use assert
to check parameters on private methods
assert param > 0;
Use null check + IllegalArgumentException
to check parameters on public methods
if (param == null) throw new IllegalArgumentException("param cannot be null");
Use null check + NullPointerException where needed
if (getChild() == null) throw new NullPointerException("node must have children");
HOWEVER, since this is question may be about catching potential null
issues most efficiently, then I have to mention my preferred method for dealing with null
is using static analysis, e.g. type annotations (e.g. @NonNull
) a la JSR-305. My favorite tool for checking them is:
The Checker Framework:
Custom pluggable types for Java
https://checkerframework.org/manual/#checker-guarantees
If its my project (e.g. not a library with a public API) and if I can use the Checker Framework throughout:
I can document my intention more clearly in the API (e.g. this parameter may not be null (the default), but this one may be null (@Nullable
; the method may return null; etc). This annotation is right at the declaration, rather than further away in the Javadoc, so is much more likely to be maintained.
static analysis is more efficient than any runtime check
static analysis will flag potential logic flaws in advance (e.g. that I tried to pass a variable that may be null to a method that only accepts a non-null parameter) rather than depending on the issue occurring at runtime.
One other bonus is that the tool lets me put the annotations in a comment (e.g. `/@Nullable/), so my library code can compatible with type-annotated projects and non-type-annotated projects (not that I have any of these).
In case the link goes dead again, here's the section from GeoTools Developer Guide:
http://data.opengeo.org/GEOT-290810-1755-708.pdf
5.1.7 Use of Assertions, IllegalArgumentException and NPE
The Java language has for a couple of years now made an assert keyword available; this keyword can be used to perform debug only checks. While there are several uses of this facility, a common one is to check method parameters on private (not public) methods. Other uses are post-conditions and invariants.
Reference: Programming With Assertions
Pre-conditions (like argument checks in private methods) are typically easy targets for assertions. Post-conditions and invariants are sometime less straighforward but more valuable, since non-trivial conditions have more risks to be broken.
Use Assert to check Parameters on Private methods
private double scale( int scaleDenominator ){
assert scaleDenominator > 0;
return 1 / (double) scaleDenominator;
}
You can enable assertions with the following command line parameter:
java -ea MyApp
You can turn only GeoTools assertions with the following command line parameter:
java -ea:org.geotools MyApp
You can disable assertions for a specific package as shown here:
java -ea:org.geotools -da:org.geotools.referencing MyApp
Use IllegalArgumentExceptions to check Parameters on Public Methods
The use of asserts on public methods is strictly discouraged; because the mistake being reported has been made in client code - be honest and tell them up front with an IllegalArgumentException when they have screwed up.
public double toScale( int scaleDenominator ){
if( scaleDenominator > 0 ){
throw new IllegalArgumentException( "scaleDenominator must be greater than 0");
}
return 1 / (double) scaleDenominator;
}
Use NullPointerException where needed
If possible perform your own null checks; throwing a IllegalArgumentException or NullPointerException with detailed information about what has gone wrong.
public double toScale( Integer scaleDenominator ){
if( scaleDenominator == null ){
throw new NullPointerException( "scaleDenominator must be provided");
}
if( scaleDenominator > 0 ){
throw new IllegalArgumentException( "scaleDenominator must be greater than 0");
}
return 1 / (double) scaleDenominator;
}