I work with Java all day long. The most used idiom (code snippet) I'm programming in Java, is to test if an object != null
before I use it. This is to avoid a NullPointerException. I find the code very ugly and it becomes unreadable.
Is there a good alternative to avoid this code snippet?
Update: Pan, I was not clear with my question. I want to address the necessity to test every object if you want to access a field or method of this object. For example:
...
if (someobject != null) {
someobject.doCalc();
}
...
In this case I will avoid a NullPointerException
, and I don't know exactly if the object is null
or not. So my code get splattered with these tests.
Nevertheless thanks a lot for your answers, I got a bunch of new insight.
This to me sounds like a reasonably common problem that junior to intermediate developers tend to face at some point: they either don't know or don't trust the contracts they are participating in and defensively overcheck for nulls. Additionally, when writing their own code, they tend to rely on returning nulls to indicate something thus requiring the caller to check for nulls.
To put this another way, there are two instances where null checking comes up:
Where null is a valid response in terms of the contract; and
Where it isn't a valid response.
(2) is easy. Either use assert
statements (assertions) or allow failure (for example, NullPointerException). Assertions are a highly-underused Java feature that was added in 1.4. The syntax is:
assert *<condition>*
or
assert *<condition>* : *<object>*
where <object>
's toString()
output will be included in the error.
An assert
statement throws an Error
(AssertionError
) if the condition is not true. By default, Java ignores assertions. You can enable assertions by passing the option -ea
to the JVM. You can enable and disable assertions for individual classes and packages. This means that you can validate code with the assertions while developing and testing, and disable them in a production environment, although my testing has shown next to no performance impact from assertions.
Not using assertions in this case is OK because the code will just fail, which is what will happen if you use assertions. The only difference is that with assertions it might happen sooner, in a more-meaningful way and possibly with extra information, which may help you to figure out why it happened if you weren't expecting it.
(1) is a little harder. If you have no control over the code you're calling then you're stuck. If null is a valid response, you have to check for it.
If it's code that you do control, however (and this is often the case), then it's a different story. Avoid using nulls as a response. With methods that return collections, it's easy: return empty collections (or arrays) instead of nulls pretty much all the time.
With non-collections it might be harder. Consider this as an example: if you have these interfaces:
public interface Action {
void doSomething();
}
public interface Parser {
Action findAction(String userInput);
}
where Parser takes raw user input and finds something to do, perhaps if you're implementing a command line interface for something. Now you might make the contract that it returns null if there's no appropriate action. That leads the null checking you're talking about.
An alternative solution is to never return null and instead use the Null Object pattern:
public class MyParser implements Parser {
private static Action DO_NOTHING = new Action() {
public void doSomething() { /* do nothing */ }
};
public Action findAction(String userInput) {
// ...
if ( /* we can't find any actions */ ) {
return DO_NOTHING;
}
}
}
Compare:
Parser parser = ParserFactory.getParser();
if (parser == null) {
// now what?
// this would be an example of where null isn't (or shouldn't be) a valid response
}
Action action = parser.findAction(someInput);
if (action == null) {
// do nothing
} else {
action.doSomething();
}
to
ParserFactory.getParser().findAction(someInput).doSomething();
which is a much better design because it leads to more concise code.
If you use (or planning to use) JetBrains Idea, a Java ide, you can use some particular annotations developed by them.
Basically, you've got @Nullable
and @NotNull
.
You can use in method and parameters, like this:
@NotNull public static String helloWorld() {
return "Hello World";
}
or
@Nullable public static String helloWorld() {
return "Hello World";
}
The second example won't compile (in Idea).
When you use the first HelloWorld() function in another piece of code:
public static void main(String[] args)
{
if(helloWorld() != null) {
System.out.println(helloWorld());
}
}
Now the idea compiler will tell you that the check is useless, since the HelloWorld() function won't return null, ever.
Using parameter
void someMethod(@NotNull someParameter) { }
if you write something like:
someMethod(null);
This won't compile.
Last example using @Nullable
@Nullable iWantToDestroyEverything() { return null; }
Doing this
iWantToDestroyEverything().something();
And you can be sure that this won't happen. :)
It's a nice way to let the compiler check something more than it usually does and to enforce your contracts to be stronger. Unfortunately, it's not supported by all the compilers.
In IntelliJ 10.5 and on, they added support for any other @Nullable @NotNull implementations.
http://blogs.jetbrains.com/idea/2011/03/more-flexible-and-configurable-nullublenotnull-annotations/
If null-values is not allowed
If your method called externally, start with something like this:
public void method(Object object) {
if (object == null) {
throw new IllegalArgumentException("...");
}
In the rest of that method, you know that it's not null.
If it is an internal method (not part of an api), just document that it cannot be null, and that's it. Example:
public String getFirst3Chars(String text) {
return text.subString(0, 3);
}
However, if your method just passes the value on, and the next method passes on etc. it could get problematic. In that case you may want to check the argument as above.
If null is allowed
This really depends. If find that I often do something like this:
if (object == null) {
// something
} else {
// something else
}
So I branch, and do two completely different things. There is no ugly code snippet, because I really need to do two different things depending on the data. For example, should I work on the input, or should I calculate a good default value?
It's actually rare for me to use the idiom "if (object != null && ...
".
It may be easier to give you examples, if you show examples of where you typically use the idiom.
Wow, I almost hate to add another answer when we have 57 different ways to recommend the NullObject pattern
, but I think that some people interested in this question may like to know that there is a proposal on the table for Java 7 to add "null-safe handling"—a streamlined syntax for if-not-equal-null logic.
The example given by Alex Miller looks like this:
public String getPostcode(Person person) {
return person?.getAddress()?.getPostcode();
}
The ?.
means only de-reference the left identifier if it is not null, otherwise evaluate the remainder of the expression as null
. Some people, like Java Posse member Dick Wall and the voters at Devoxx really love this proposal, but there is opposition too, on the grounds that it will actually encourage more use of null
as a sentinel value.
Update: An official proposal for a null-safe operator in Java 7 has been submitted under Project Coin. The syntax is a little different than the example above, but it's the same notion.
Update: The null-safe operator proposal didn't make it into Project Coin. So, you won't be seeing this syntax in Java 7.
If undefined values are not permitted:
You might configure your IDE to warn you about potential null dereferencing. E.g. in Eclipse, see Preferences > Java > Compiler > Errors/Warnings/Null analysis.
If undefined values are permitted:
If you want to define a new API where undefined values make sense, use the Option Pattern (may be familiar from functional languages). It has the following advantages:
- It is stated explicitly in the API whether an input or output exists or not.
- The compiler forces you to handle the "undefined" case.
- Option is a monad, so there is no need for verbose null checking, just use map/foreach/getOrElse or a similar combinator to safely use the value (example).
Java 8 has a built-in Optional
class (recommended); for earlier versions, there are library alternatives, for example Guava's Optional
or FunctionalJava's Option
. But like many functional-style patterns, using Option in Java (even 8) results in quite some boilerplate, which you can reduce using a less verbose JVM language, e.g. Scala or Xtend.
If you have to deal with an API which might return nulls, you can't do much in Java. Xtend and Groovy have the Elvis operator ?:
and the null-safe dereference operator ?.
, but note that this returns null in case of a null reference, so it just "defers" the proper handling of null.
Depending on what kind of objects you are checking you may be able to use some of the classes in the apache commons such as: apache commons lang and apache commons collections
Example:
String foo;
...
if( StringUtils.isBlank( foo ) ) {
///do something
}
or (depending on what you need to check):
String foo;
...
if( StringUtils.isEmpty( foo ) ) {
///do something
}
The StringUtils class is only one of many; there are quite a few good classes in the commons that do null safe manipulation.
Here follows an example of how you can use null vallidation in JAVA when you include apache library(commons-lang-2.4.jar)
public DOCUMENT read(String xml, ValidationEventHandler validationEventHandler) {
**Validate.notNull(validationEventHandler,"ValidationHandler not Injected");**
return read(new StringReader(xml), true, validationEventHandler);
}
And if you are using Spring, Spring also has the same functionality in its package, see library(spring-2.4.6.jar)
Example on how to use this static classf from spring(org.springframework.util.Assert)
Assert.notNull(validationEventHandler,"ValidationHandler not Injected");
Only for this situation - Avoiding checking for null before a string compare:
if ( foo.equals("bar") ) {
// ...
}
will result in a NullPointerException
if foo
doesn't exist.
You can avoid that if you compare your String
s like this:
if ( "bar".equals(foo) ) {
// ...
}
- If you consider an object should not be null (or it is a bug) use an assert.
- If your method doesn't accept null params say it in the javadoc and use an assert.
You have to check for object != null only if you want to handle the case where the object may be null...
There is a proposal to add new annotations in Java7 to help with null / notnull params: http://tech.puredanger.com/java7/#jsr308
I'm a fan of "fail fast" code. Ask yourself - are you doing something useful in the case where the parameter is null? If you don't have a clear answer for what your code should do in that case... I.e. it should never be null in the first place, then ignore it and allow a NullPointerException to be thrown. The calling code will make just as much sense of an NPE as it would an IllegalArgumentException, but it'll be easier for the developer to debug and understand what went wrong if an NPE is thrown rather than your code attempting to execute some other unexpected contingency logic - which ultimately results in the application failing anyway.
The google collections framework offers a good and elegant way to achieve the null check.
There is a method in a library class like this:
static <T> T checkNotNull(T e){
if(e == null){
throw new NullPointerException();
}
return e;
}
And the usage is (with import static
):
...
void foo(int a, Person p){
if(checkNotNull(p).getAge() > a){
...
}else{
...
}
}
...
or in your example:
checkNotNull(someobject).doCalc();
Rather than Null Object Pattern -- which has its uses -- you might consider situations where the null object is a bug.
When the exception is thrown, examine the stack trace and work through the bug.
Sometimes, you have methods that operate on its parameters that define a symmetric operation: a.f(b); <-> b.f(a);
If you know b can never be null, you can just swap it. most useful for equals: instead of foo.equals("bar");
better do "bar".equals(foo);
,
Ultimately, the only way to completely solve this problem is by using a different programming language:
- In Objective-C, you can do the equivalent of invoking a method on
nil
, and absolutely nothing will happen. This makes most null checks unnecessary but can make errors much harder to diagnose. - In Nice, a Java-derivated language, there are two versions of all types: a potentially-null version and a not-null version. You can only invoke methods on not-null types. Potentially-null types can be converted to not-null types through explicit checking for null. This makes it much easier to know where null checks are necessary and where they aren't.
In addition to using assert
you can use the following :
if (someobject == null) {
// handle null here then move on.
}
This is slightly better than :
if (someobject != null) {
.....
.....
.....
}
Asking that question points out that you may be interested in error handling strategies. Your team's architect should decide how to work errors. There are several ways to do this:
allow the Exceptions to ripple through - catch them at the 'main loop' or in some other managing routine.
check for error conditions and handle them appropriately
Sure do have a look at Aspect Oriented Programming, too - they have neat ways to insert if( o == null ) handleNull()
into your bytecode.
Common "problem" in Java indeed.
First, my thoughts on this:
I consider that it is bad to "eat" something when NULL was passed where NULL isn't a valid value. If you're not exiting the method with some sort of error then it means nothing went wrong in your method which is not true. Then you probably return null in this case, and in the receiving method you again check for null, and it never ends, and you end up with "if != null", etc..
So, imho, null must be a critical error which prevents further execution (i.e. where null is not a valid value).
The way I solve this problem is this:
First, I follow this convetion:
all public methods / API always check for null its arguments
all private methods do not check for null since they are controlled methods (just let die with NPE in case it wasn't handled above)
the only other methods which do not check for null are utility methods. They are public, but if you call them for some reason, you know what parameters you pass. This is like trying to boil water in the kettle without providing water...
And finally, in the code, the first line of the public method goes like this:
ValidationUtils.getNullValidator().addParam(plans, "plans").addParam(persons, "persons").validate();
note that addParam() returns self, so that you can add more params to check.
method validate()
will throw checked ValidationException
if any of the params is null (checked or unchecked is more a design/taste issue, but my ValidationException
is checked).
void validate() throws ValidationException;
The message will contain the following text if, for example, "plans" is null:
"Illegal argument value null is encountered for parameter [plans]"
As you can see, 2nd value in the addParam() method (string) is needed for the user message, because you cannot easily detect passed-in variable name, even with reflection (not subject of this post anyway...).
And yes, we know that beyond this line we will no longer encounter a null value so we just safely invoke methods on those objects.
This way, code is clean, easy maintainable and readable.
- Null is not a 'problem'. It is integral part of complete modeling tool set. Software aims to model complexity of the world and null bears its burden. Some programming languages are designed to be concurrent-oriented some other use empty collections and have no nulls. They are like different tool sets designed for specific 'application areas'. Null indicates 'No data' or 'Unknown' in java and the like. So it is appropriate to use nulls for these purposes. I don't prefer 'Null object' pattern, I think it rise Who will guard the guards problem.
If you ask me what is the name of my girlfriend I'll tell you that I have no girlfriend. In 'java language' I'll return null. Some other 'business logic' could consider it necessary to throw a meaningful exception to indicate some problem that can't be (or don't want to be) solved right there and delegate it somewhere higher in the stack. For 'unknown question' give 'unknown answer'. Checking arguments for null once inside method before usage relieves multiple callers from checking them before call.
public Photo getPhotoOfThePerson(Person person) {
if (person == null)
return null;
// grabbing some resources or intensive calculation
// using person object anyhow
}previous leads to normal logic flow to get no photo of non-existent girlfriend from my photo library.
getPhotoOfThePerson(me.getGirlfriend())
and fits with new coming java api (looking forward)
getPhotoByName(me.getGirlfriend()?.getName())
NullPointerException
is subclass of anException
. Thus it is a form ofThrowable
that indicates conditions that a reasonable application might want to catch (javadoc)! To utilize The first most advantage of Exceptions and separate Error-Handling Code from 'Regular' Code (according to creators of java) it is appropriate, as for me, to catchNullPointerException
.public Photo getGirlfriendPhoto() {
try {
return appContext.getPhotoDataSource().getPhotoByName(me.getGirlfriend().getName());
} catch (NullPointerException e) {
return null;
}
}Questions could arise:
q. What if
getPhotoDataSource()
return null?
a. It is up to business logic. If I fail to find photo album I'll show you no photos. What if appContext is not initialized?.. This method's business logic put up with this. If some logic should be more strict then throwing an exception it is part of business logic and explicit check for null should be used (case 4). New Java Null-safe API fits better here to specify selectively what implies and what does not imply to be initialized to be fail-fast in case of programmer errors.q. Redundant code could be executed and unnecessary resources could be grabbed.
a. It could take place ifgetPhotoByName()
would try to open DB connection, createPreparedStatement
and use person name as SQL parameter at last. Approach for unknown question give unknown answer (case 2) works here. Before grabbing resources method should check parameters and return 'unknown' result if need.q. This approach have performance penalty due to try closure opening.
a. Software should be easy to understand and modify firstly. Only after this one could think about performance only if needed! and where needed! (source, and many others).PS. This approach will be as reasonable to use as Separate Error-Handling Code from "Regular" Code principle is reasonable to use in some place. Consider next example:
public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {
try {
Result1 result1 = performSomeCalculation(predicate);
Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());
Result3 result3 = performThirdCalculation(result2.getSomeProperty());
Result4 result4 = performLastCalculation(result3.getSomeProperty());
return result4.getSomeProperty();
} catch (NullPointerException e) {
return null;
}
}
public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {
SomeValue result = null;
if (predicate != null) {
Result1 result1 = performSomeCalculation(predicate);
if (result1 != null && result1.getSomeProperty() != null) {
Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());
if (result2 != null && result2.getSomeProperty() != null) {
Result3 result3 = performThirdCalculation(result2.getSomeProperty());
if (result3 != null && result3.getSomeProperty() != null) {
Result4 result4 = performLastCalculation(result3.getSomeProperty());
if (result4 != null) {
result = result4.getSomeProperty();
}
}
}
}
}
return result;
}Check for 'No data' only if business logic implies.
public void updatePersonPhoneNumber(Long personId, String phoneNumber) {
if (personId == null)
return;
DataSource dataSource = appContext.getStuffDataSource();
Person person = dataSource.getPersonById(personId);
if (person != null) {
person.setPhoneNumber(phoneNumber);
dataSource.updatePerson(person);
} else {
Person = new Person(personId);
person.setPhoneNumber(phoneNumber);
dataSource.insertPerson(person);
}
}and
public void updatePersonPhoneNumber(Long personId, String phoneNumber) {
if (personId == null)
return;
DataSource dataSource = appContext.getStuffDataSource();
Person person = dataSource.getPersonById(personId);
if (person == null)
throw new SomeReasonableUserException("What are you thinking about ???");
person.setPhoneNumber(phoneNumber);
dataSource.updatePerson(person);
}If appContext or dataSource are not initialized NullPointerException reveals programmer error somewhere in initialization stuff and it should be fixed exactly there. Current methods business logic implies these to be ready for use.
Java 7 has a new java.util.Objects
utility class on which there is a requireNonNull()
method. All this does is throw a NullPointerException
if its argument is null, but it cleans up the code a bit. Example:
Objects.requireNonNull(someObject);
someObject.doCalc();
I like articles from Nat Pryce, here are the links:
In the articles there is also a link to a git repository for a java Maybe Type which i find interesting, but I don't think it alone could decrease the checking code bloat. After doing some research on the Internet, I think != null code bloat could be decreased mainly by carefull design
just don't ever use null, don't allow it
in my classes, most fields and local vars have a non-null default values, and I add contract statements (always-on asserts) everywhere in the code to make sure this is being enforced (since it's more succinct, and more expressive than letting it come up as a NPE and then having to resolve the line number, etc).
once i adopted this practice, I noticed that the problems seemed to fix themselves, you'd catch things much earlier in the development process just by accident and realize you had a weak spot.. and more importantly.. it helps encapsulate different modules' concerns, different modules can 'trust' each other, and no more littering the code with if = null else constructs!
this is defensive program and results in much cleaner code in the long run. always sanitize the data, e.g. here by enforcing rigid standards, and the problems go away.
class C {
private final MyType mustBeSet;
public C(MyType mything) {
mustBeSet=Contract.notNull(mything);
}
private String name = "<unknown>";
public void setName(String s) {
name = Contract.notNull(s);
}
}
class Contract {
public static <T> T notNull(T t) { if (t == null) { throw new ContractException("argument must be non-null"); return t; }
}
the contracts are like mini-unit tests which are always running, even in production, and when things fail, you know why, rather than a random NPE you have to somehow figure out
With Java 8 come the new java.util.Optional
class that arguably solves some of the problem. One can at least say that it improves the readability of the code, and in the case of public API's make the API's contract clearer to the client developer.
They work like that :
An optional object for a given type (Fruit
) is created as the return type of a method. It can be empty or contain a Fruit
object :
public static Optional<Fruit> find(String name, List<Fruit> fruits) {
for(Fruit fruit : fruits) {
if(fruit.getName().equals(name)) {
return Optional.of(fruit);
}
}
return Optional.empty();
}
No look at this code where we search a list of Fruit
(fruits
) for a given Fruit instance :
Optional<Fruit> found = find("lemon", fruits);
if(found.isPresent()) {
Fruit fruit = found.get();
String name = fruit.getName();
}
Of course, the check for null/empty value is still necessary, but at least the developer is conscious that the value might be empty and the risk of forgetting to check is limited.
In an API built from scratch using Optional
whenever a return value might be empty, and returning a plain object only when it cannot be null
(convention), the client code might abandon null checks on simple object return values...
Of course Optional
could also be used as method argument, perhaps a better way to indicate optional arguments than 5 or 10 overloading methods in some cases.
Optional
offers other convenient methods, such as orElse
that allow the use of a default value, and ifPresent
that woks with lamba expressions.
I invite you te read this article (my main source for writing this answer) in which the NullPointerException
(and in general null pointer) problematic as well as the (partial) solution brought by Optional
are well explained : http://java.dzone.com/articles/java-optional-objects
Guava, a very useful core library by Google, has a nice and useful API to avoid nulls. I find UsingAndAvoidingNullExplained very helpful.
One more alternative:
The following simple function helps to hide the null-check (I don't know why, but I haven't found it as part of the some common library):
public static <T> boolean isNull(T argument) {
return (argument == null);
}
You could now write
if (!isNull(someobject)) {
someobject.doCalc();
}
which is IMO a better way of expressing != null
.
I've tried the NullObjectPattern
but for me is not always the best way to go. There are sometimes when a "no action" is not appropiate.
NullPointerException
is a Runtime exception that means it's developers fault and with enough experience it tells you exactly where is the error.
Now to the answer:
Try to make all your attributes and its accessors as private as possible or avoid to expose them to the clients at all. You can have the argument values in the constructor of course, but by reducing the scope you don't let the client class pass an invalid value. If you need to modify the values, you can always create a new object
. You check the values in the constructor only once and in the rest of the methods you can be almost sure that the values are not null.
Of course, experience is the better way to understand and apply this suggestion.
Byte!
- Never initialise variables to null.
- If (1) is not possible, initialise all collections and arrays to empty collections/arrays.
Doing this in your own code and you can avoid != null checks.
Most of the time null checks seem to guard loops over collections or arrays, so just initialise them empty, you won't need any null checks.
// Bad
ArrayList<String> lemmings;
String[] names;
void checkLemmings() {
if (lemmings != null) for(lemming: lemmings) {
// do something
}
}
// Good
ArrayList<String> lemmings = new ArrayList<String>();
String[] names = {};
void checkLemmings() {
for(lemming: lemmings) {
// do something
}
}
There is a tiny overhead in this, but it's worth it for cleaner code and less NullPointerExceptions.
public static <T> T ifNull(T toCheck, T ifNull){
if(toCheck == null){
return ifNull;
}
return toCheck;
}
Wherever you pass an array or a Vector, initialise these to empty ones, instead of null. - This way you can avoid lots of checking for null and all is good :)
public class NonNullThing {
Vector vectorField = new Vector();
int[] arrayField = new int[0];
public NonNullThing() {
// etc
}
}
If ( "bar".equals(foo) ) { // ... }
I do agree with this, because you get the string not the parameter which is we do not know about the value.
I work with Java all day long. The most used idiom (code snippet) I'm programming in Java, is to test if an object != null
before I use it. This is to avoid a NullPointerException. I find the code very ugly and it becomes unreadable.
Is there a good alternative to avoid this code snippet?
Update: Pan, I was not clear with my question. I want to address the necessity to test every object if you want to access a field or method of this object. For example:
...
if (someobject != null) {
someobject.doCalc();
}
...
In this case I will avoid a NullPointerException
, and I don't know exactly if the object is null
or not. So my code get splattered with these tests.
Nevertheless thanks a lot for your answers, I got a bunch of new insight.
This to me sounds like a reasonably common problem that junior to intermediate developers tend to face at some point: they either don't know or don't trust the contracts they are participating in and defensively overcheck for nulls. Additionally, when writing their own code, they tend to rely on returning nulls to indicate something thus requiring the caller to check for nulls.
To put this another way, there are two instances where null checking comes up:
Where null is a valid response in terms of the contract; and
Where it isn't a valid response.
(2) is easy. Either use assert
statements (assertions) or allow failure (for example, NullPointerException). Assertions are a highly-underused Java feature that was added in 1.4. The syntax is:
assert *<condition>*
or
assert *<condition>* : *<object>*
where <object>
's toString()
output will be included in the error.
An assert
statement throws an Error
(AssertionError
) if the condition is not true. By default, Java ignores assertions. You can enable assertions by passing the option -ea
to the JVM. You can enable and disable assertions for individual classes and packages. This means that you can validate code with the assertions while developing and testing, and disable them in a production environment, although my testing has shown next to no performance impact from assertions.
Not using assertions in this case is OK because the code will just fail, which is what will happen if you use assertions. The only difference is that with assertions it might happen sooner, in a more-meaningful way and possibly with extra information, which may help you to figure out why it happened if you weren't expecting it.
(1) is a little harder. If you have no control over the code you're calling then you're stuck. If null is a valid response, you have to check for it.
If it's code that you do control, however (and this is often the case), then it's a different story. Avoid using nulls as a response. With methods that return collections, it's easy: return empty collections (or arrays) instead of nulls pretty much all the time.
With non-collections it might be harder. Consider this as an example: if you have these interfaces:
public interface Action {
void doSomething();
}
public interface Parser {
Action findAction(String userInput);
}
where Parser takes raw user input and finds something to do, perhaps if you're implementing a command line interface for something. Now you might make the contract that it returns null if there's no appropriate action. That leads the null checking you're talking about.
An alternative solution is to never return null and instead use the Null Object pattern:
public class MyParser implements Parser {
private static Action DO_NOTHING = new Action() {
public void doSomething() { /* do nothing */ }
};
public Action findAction(String userInput) {
// ...
if ( /* we can't find any actions */ ) {
return DO_NOTHING;
}
}
}
Compare:
Parser parser = ParserFactory.getParser();
if (parser == null) {
// now what?
// this would be an example of where null isn't (or shouldn't be) a valid response
}
Action action = parser.findAction(someInput);
if (action == null) {
// do nothing
} else {
action.doSomething();
}
to
ParserFactory.getParser().findAction(someInput).doSomething();
which is a much better design because it leads to more concise code.
If you use (or planning to use) JetBrains Idea, a Java ide, you can use some particular annotations developed by them.
Basically, you've got @Nullable
and @NotNull
.
You can use in method and parameters, like this:
@NotNull public static String helloWorld() {
return "Hello World";
}
or
@Nullable public static String helloWorld() {
return "Hello World";
}
The second example won't compile (in Idea).
When you use the first HelloWorld() function in another piece of code:
public static void main(String[] args)
{
if(helloWorld() != null) {
System.out.println(helloWorld());
}
}
Now the idea compiler will tell you that the check is useless, since the HelloWorld() function won't return null, ever.
Using parameter
void someMethod(@NotNull someParameter) { }
if you write something like:
someMethod(null);
This won't compile.
Last example using @Nullable
@Nullable iWantToDestroyEverything() { return null; }
Doing this
iWantToDestroyEverything().something();
And you can be sure that this won't happen. :)
It's a nice way to let the compiler check something more than it usually does and to enforce your contracts to be stronger. Unfortunately, it's not supported by all the compilers.
In IntelliJ 10.5 and on, they added support for any other @Nullable @NotNull implementations.
http://blogs.jetbrains.com/idea/2011/03/more-flexible-and-configurable-nullublenotnull-annotations/
If null-values is not allowed
If your method called externally, start with something like this:
public void method(Object object) {
if (object == null) {
throw new IllegalArgumentException("...");
}
In the rest of that method, you know that it's not null.
If it is an internal method (not part of an api), just document that it cannot be null, and that's it. Example:
public String getFirst3Chars(String text) {
return text.subString(0, 3);
}
However, if your method just passes the value on, and the next method passes on etc. it could get problematic. In that case you may want to check the argument as above.
If null is allowed
This really depends. If find that I often do something like this:
if (object == null) {
// something
} else {
// something else
}
So I branch, and do two completely different things. There is no ugly code snippet, because I really need to do two different things depending on the data. For example, should I work on the input, or should I calculate a good default value?
It's actually rare for me to use the idiom "if (object != null && ...
".
It may be easier to give you examples, if you show examples of where you typically use the idiom.
Wow, I almost hate to add another answer when we have 57 different ways to recommend the NullObject pattern
, but I think that some people interested in this question may like to know that there is a proposal on the table for Java 7 to add "null-safe handling"—a streamlined syntax for if-not-equal-null logic.
The example given by Alex Miller looks like this:
public String getPostcode(Person person) {
return person?.getAddress()?.getPostcode();
}
The ?.
means only de-reference the left identifier if it is not null, otherwise evaluate the remainder of the expression as null
. Some people, like Java Posse member Dick Wall and the voters at Devoxx really love this proposal, but there is opposition too, on the grounds that it will actually encourage more use of null
as a sentinel value.
Update: An official proposal for a null-safe operator in Java 7 has been submitted under Project Coin. The syntax is a little different than the example above, but it's the same notion.
Update: The null-safe operator proposal didn't make it into Project Coin. So, you won't be seeing this syntax in Java 7.
If undefined values are not permitted:
You might configure your IDE to warn you about potential null dereferencing. E.g. in Eclipse, see Preferences > Java > Compiler > Errors/Warnings/Null analysis.
If undefined values are permitted:
If you want to define a new API where undefined values make sense, use the Option Pattern (may be familiar from functional languages). It has the following advantages:
- It is stated explicitly in the API whether an input or output exists or not.
- The compiler forces you to handle the "undefined" case.
- Option is a monad, so there is no need for verbose null checking, just use map/foreach/getOrElse or a similar combinator to safely use the value (example).
Java 8 has a built-in Optional
class (recommended); for earlier versions, there are library alternatives, for example Guava's Optional
or FunctionalJava's Option
. But like many functional-style patterns, using Option in Java (even 8) results in quite some boilerplate, which you can reduce using a less verbose JVM language, e.g. Scala or Xtend.
If you have to deal with an API which might return nulls, you can't do much in Java. Xtend and Groovy have the Elvis operator ?:
and the null-safe dereference operator ?.
, but note that this returns null in case of a null reference, so it just "defers" the proper handling of null.
Depending on what kind of objects you are checking you may be able to use some of the classes in the apache commons such as: apache commons lang and apache commons collections
Example:
String foo;
...
if( StringUtils.isBlank( foo ) ) {
///do something
}
or (depending on what you need to check):
String foo;
...
if( StringUtils.isEmpty( foo ) ) {
///do something
}
The StringUtils class is only one of many; there are quite a few good classes in the commons that do null safe manipulation.
Here follows an example of how you can use null vallidation in JAVA when you include apache library(commons-lang-2.4.jar)
public DOCUMENT read(String xml, ValidationEventHandler validationEventHandler) {
**Validate.notNull(validationEventHandler,"ValidationHandler not Injected");**
return read(new StringReader(xml), true, validationEventHandler);
}
And if you are using Spring, Spring also has the same functionality in its package, see library(spring-2.4.6.jar)
Example on how to use this static classf from spring(org.springframework.util.Assert)
Assert.notNull(validationEventHandler,"ValidationHandler not Injected");
Only for this situation - Avoiding checking for null before a string compare:
if ( foo.equals("bar") ) {
// ...
}
will result in a NullPointerException
if foo
doesn't exist.
You can avoid that if you compare your String
s like this:
if ( "bar".equals(foo) ) {
// ...
}
- If you consider an object should not be null (or it is a bug) use an assert.
- If your method doesn't accept null params say it in the javadoc and use an assert.
You have to check for object != null only if you want to handle the case where the object may be null...
There is a proposal to add new annotations in Java7 to help with null / notnull params: http://tech.puredanger.com/java7/#jsr308
I'm a fan of "fail fast" code. Ask yourself - are you doing something useful in the case where the parameter is null? If you don't have a clear answer for what your code should do in that case... I.e. it should never be null in the first place, then ignore it and allow a NullPointerException to be thrown. The calling code will make just as much sense of an NPE as it would an IllegalArgumentException, but it'll be easier for the developer to debug and understand what went wrong if an NPE is thrown rather than your code attempting to execute some other unexpected contingency logic - which ultimately results in the application failing anyway.
The google collections framework offers a good and elegant way to achieve the null check.
There is a method in a library class like this:
static <T> T checkNotNull(T e){
if(e == null){
throw new NullPointerException();
}
return e;
}
And the usage is (with import static
):
...
void foo(int a, Person p){
if(checkNotNull(p).getAge() > a){
...
}else{
...
}
}
...
or in your example:
checkNotNull(someobject).doCalc();
Rather than Null Object Pattern -- which has its uses -- you might consider situations where the null object is a bug.
When the exception is thrown, examine the stack trace and work through the bug.
Sometimes, you have methods that operate on its parameters that define a symmetric operation: a.f(b); <-> b.f(a);
If you know b can never be null, you can just swap it. most useful for equals: instead of foo.equals("bar");
better do "bar".equals(foo);
,
Ultimately, the only way to completely solve this problem is by using a different programming language:
- In Objective-C, you can do the equivalent of invoking a method on
nil
, and absolutely nothing will happen. This makes most null checks unnecessary but can make errors much harder to diagnose. - In Nice, a Java-derivated language, there are two versions of all types: a potentially-null version and a not-null version. You can only invoke methods on not-null types. Potentially-null types can be converted to not-null types through explicit checking for null. This makes it much easier to know where null checks are necessary and where they aren't.
In addition to using assert
you can use the following :
if (someobject == null) {
// handle null here then move on.
}
This is slightly better than :
if (someobject != null) {
.....
.....
.....
}
Asking that question points out that you may be interested in error handling strategies. Your team's architect should decide how to work errors. There are several ways to do this:
allow the Exceptions to ripple through - catch them at the 'main loop' or in some other managing routine.
check for error conditions and handle them appropriately
Sure do have a look at Aspect Oriented Programming, too - they have neat ways to insert if( o == null ) handleNull()
into your bytecode.
Common "problem" in Java indeed.
First, my thoughts on this:
I consider that it is bad to "eat" something when NULL was passed where NULL isn't a valid value. If you're not exiting the method with some sort of error then it means nothing went wrong in your method which is not true. Then you probably return null in this case, and in the receiving method you again check for null, and it never ends, and you end up with "if != null", etc..
So, imho, null must be a critical error which prevents further execution (i.e. where null is not a valid value).
The way I solve this problem is this:
First, I follow this convetion:
all public methods / API always check for null its arguments
all private methods do not check for null since they are controlled methods (just let die with NPE in case it wasn't handled above)
the only other methods which do not check for null are utility methods. They are public, but if you call them for some reason, you know what parameters you pass. This is like trying to boil water in the kettle without providing water...
And finally, in the code, the first line of the public method goes like this:
ValidationUtils.getNullValidator().addParam(plans, "plans").addParam(persons, "persons").validate();
note that addParam() returns self, so that you can add more params to check.
method validate()
will throw checked ValidationException
if any of the params is null (checked or unchecked is more a design/taste issue, but my ValidationException
is checked).
void validate() throws ValidationException;
The message will contain the following text if, for example, "plans" is null:
"Illegal argument value null is encountered for parameter [plans]"
As you can see, 2nd value in the addParam() method (string) is needed for the user message, because you cannot easily detect passed-in variable name, even with reflection (not subject of this post anyway...).
And yes, we know that beyond this line we will no longer encounter a null value so we just safely invoke methods on those objects.
This way, code is clean, easy maintainable and readable.
- Null is not a 'problem'. It is integral part of complete modeling tool set. Software aims to model complexity of the world and null bears its burden. Some programming languages are designed to be concurrent-oriented some other use empty collections and have no nulls. They are like different tool sets designed for specific 'application areas'. Null indicates 'No data' or 'Unknown' in java and the like. So it is appropriate to use nulls for these purposes. I don't prefer 'Null object' pattern, I think it rise Who will guard the guards problem.
If you ask me what is the name of my girlfriend I'll tell you that I have no girlfriend. In 'java language' I'll return null. Some other 'business logic' could consider it necessary to throw a meaningful exception to indicate some problem that can't be (or don't want to be) solved right there and delegate it somewhere higher in the stack. For 'unknown question' give 'unknown answer'. Checking arguments for null once inside method before usage relieves multiple callers from checking them before call.
public Photo getPhotoOfThePerson(Person person) {
if (person == null)
return null;
// grabbing some resources or intensive calculation
// using person object anyhow
}previous leads to normal logic flow to get no photo of non-existent girlfriend from my photo library.
getPhotoOfThePerson(me.getGirlfriend())
and fits with new coming java api (looking forward)
getPhotoByName(me.getGirlfriend()?.getName())
NullPointerException
is subclass of anException
. Thus it is a form ofThrowable
that indicates conditions that a reasonable application might want to catch (javadoc)! To utilize The first most advantage of Exceptions and separate Error-Handling Code from 'Regular' Code (according to creators of java) it is appropriate, as for me, to catchNullPointerException
.public Photo getGirlfriendPhoto() {
try {
return appContext.getPhotoDataSource().getPhotoByName(me.getGirlfriend().getName());
} catch (NullPointerException e) {
return null;
}
}Questions could arise:
q. What if
getPhotoDataSource()
return null?
a. It is up to business logic. If I fail to find photo album I'll show you no photos. What if appContext is not initialized?.. This method's business logic put up with this. If some logic should be more strict then throwing an exception it is part of business logic and explicit check for null should be used (case 4). New Java Null-safe API fits better here to specify selectively what implies and what does not imply to be initialized to be fail-fast in case of programmer errors.q. Redundant code could be executed and unnecessary resources could be grabbed.
a. It could take place ifgetPhotoByName()
would try to open DB connection, createPreparedStatement
and use person name as SQL parameter at last. Approach for unknown question give unknown answer (case 2) works here. Before grabbing resources method should check parameters and return 'unknown' result if need.q. This approach have performance penalty due to try closure opening.
a. Software should be easy to understand and modify firstly. Only after this one could think about performance only if needed! and where needed! (source, and many others).PS. This approach will be as reasonable to use as Separate Error-Handling Code from "Regular" Code principle is reasonable to use in some place. Consider next example:
public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {
try {
Result1 result1 = performSomeCalculation(predicate);
Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());
Result3 result3 = performThirdCalculation(result2.getSomeProperty());
Result4 result4 = performLastCalculation(result3.getSomeProperty());
return result4.getSomeProperty();
} catch (NullPointerException e) {
return null;
}
}
public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {
SomeValue result = null;
if (predicate != null) {
Result1 result1 = performSomeCalculation(predicate);
if (result1 != null && result1.getSomeProperty() != null) {
Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());
if (result2 != null && result2.getSomeProperty() != null) {
Result3 result3 = performThirdCalculation(result2.getSomeProperty());
if (result3 != null && result3.getSomeProperty() != null) {
Result4 result4 = performLastCalculation(result3.getSomeProperty());
if (result4 != null) {
result = result4.getSomeProperty();
}
}
}
}
}
return result;
}Check for 'No data' only if business logic implies.
public void updatePersonPhoneNumber(Long personId, String phoneNumber) {
if (personId == null)
return;
DataSource dataSource = appContext.getStuffDataSource();
Person person = dataSource.getPersonById(personId);
if (person != null) {
person.setPhoneNumber(phoneNumber);
dataSource.updatePerson(person);
} else {
Person = new Person(personId);
person.setPhoneNumber(phoneNumber);
dataSource.insertPerson(person);
}
}and
public void updatePersonPhoneNumber(Long personId, String phoneNumber) {
if (personId == null)
return;
DataSource dataSource = appContext.getStuffDataSource();
Person person = dataSource.getPersonById(personId);
if (person == null)
throw new SomeReasonableUserException("What are you thinking about ???");
person.setPhoneNumber(phoneNumber);
dataSource.updatePerson(person);
}If appContext or dataSource are not initialized NullPointerException reveals programmer error somewhere in initialization stuff and it should be fixed exactly there. Current methods business logic implies these to be ready for use.
Java 7 has a new java.util.Objects
utility class on which there is a requireNonNull()
method. All this does is throw a NullPointerException
if its argument is null, but it cleans up the code a bit. Example:
Objects.requireNonNull(someObject);
someObject.doCalc();
I like articles from Nat Pryce, here are the links:
In the articles there is also a link to a git repository for a java Maybe Type which i find interesting, but I don't think it alone could decrease the checking code bloat. After doing some research on the Internet, I think != null code bloat could be decreased mainly by carefull design
just don't ever use null, don't allow it
in my classes, most fields and local vars have a non-null default values, and I add contract statements (always-on asserts) everywhere in the code to make sure this is being enforced (since it's more succinct, and more expressive than letting it come up as a NPE and then having to resolve the line number, etc).
once i adopted this practice, I noticed that the problems seemed to fix themselves, you'd catch things much earlier in the development process just by accident and realize you had a weak spot.. and more importantly.. it helps encapsulate different modules' concerns, different modules can 'trust' each other, and no more littering the code with if = null else constructs!
this is defensive program and results in much cleaner code in the long run. always sanitize the data, e.g. here by enforcing rigid standards, and the problems go away.
class C {
private final MyType mustBeSet;
public C(MyType mything) {
mustBeSet=Contract.notNull(mything);
}
private String name = "<unknown>";
public void setName(String s) {
name = Contract.notNull(s);
}
}
class Contract {
public static <T> T notNull(T t) { if (t == null) { throw new ContractException("argument must be non-null"); return t; }
}
the contracts are like mini-unit tests which are always running, even in production, and when things fail, you know why, rather than a random NPE you have to somehow figure out
With Java 8 come the new java.util.Optional
class that arguably solves some of the problem. One can at least say that it improves the readability of the code, and in the case of public API's make the API's contract clearer to the client developer.
They work like that :
An optional object for a given type (Fruit
) is created as the return type of a method. It can be empty or contain a Fruit
object :
public static Optional<Fruit> find(String name, List<Fruit> fruits) {
for(Fruit fruit : fruits) {
if(fruit.getName().equals(name)) {
return Optional.of(fruit);
}
}
return Optional.empty();
}
No look at this code where we search a list of Fruit
(fruits
) for a given Fruit instance :
Optional<Fruit> found = find("lemon", fruits);
if(found.isPresent()) {
Fruit fruit = found.get();
String name = fruit.getName();
}
Of course, the check for null/empty value is still necessary, but at least the developer is conscious that the value might be empty and the risk of forgetting to check is limited.
In an API built from scratch using Optional
whenever a return value might be empty, and returning a plain object only when it cannot be null
(convention), the client code might abandon null checks on simple object return values...
Of course Optional
could also be used as method argument, perhaps a better way to indicate optional arguments than 5 or 10 overloading methods in some cases.
Optional
offers other convenient methods, such as orElse
that allow the use of a default value, and ifPresent
that woks with lamba expressions.
I invite you te read this article (my main source for writing this answer) in which the NullPointerException
(and in general null pointer) problematic as well as the (partial) solution brought by Optional
are well explained : http://java.dzone.com/articles/java-optional-objects
Guava, a very useful core library by Google, has a nice and useful API to avoid nulls. I find UsingAndAvoidingNullExplained very helpful.
One more alternative:
The following simple function helps to hide the null-check (I don't know why, but I haven't found it as part of the some common library):
public static <T> boolean isNull(T argument) {
return (argument == null);
}
You could now write
if (!isNull(someobject)) {
someobject.doCalc();
}
which is IMO a better way of expressing != null
.
I've tried the NullObjectPattern
but for me is not always the best way to go. There are sometimes when a "no action" is not appropiate.
NullPointerException
is a Runtime exception that means it's developers fault and with enough experience it tells you exactly where is the error.
Now to the answer:
Try to make all your attributes and its accessors as private as possible or avoid to expose them to the clients at all. You can have the argument values in the constructor of course, but by reducing the scope you don't let the client class pass an invalid value. If you need to modify the values, you can always create a new object
. You check the values in the constructor only once and in the rest of the methods you can be almost sure that the values are not null.
Of course, experience is the better way to understand and apply this suggestion.
Byte!
- Never initialise variables to null.
- If (1) is not possible, initialise all collections and arrays to empty collections/arrays.
Doing this in your own code and you can avoid != null checks.
Most of the time null checks seem to guard loops over collections or arrays, so just initialise them empty, you won't need any null checks.
// Bad
ArrayList<String> lemmings;
String[] names;
void checkLemmings() {
if (lemmings != null) for(lemming: lemmings) {
// do something
}
}
// Good
ArrayList<String> lemmings = new ArrayList<String>();
String[] names = {};
void checkLemmings() {
for(lemming: lemmings) {
// do something
}
}
There is a tiny overhead in this, but it's worth it for cleaner code and less NullPointerExceptions.
public static <T> T ifNull(T toCheck, T ifNull){
if(toCheck == null){
return ifNull;
}
return toCheck;
}
Wherever you pass an array or a Vector, initialise these to empty ones, instead of null. - This way you can avoid lots of checking for null and all is good :)
public class NonNullThing {
Vector vectorField = new Vector();
int[] arrayField = new int[0];
public NonNullThing() {
// etc
}
}
If ( "bar".equals(foo) ) { // ... }
I do agree with this, because you get the string not the parameter which is we do not know about the value.
0 commentaires:
Enregistrer un commentaire