Avoid the null checks using null statement
Overview
Normally, null variables or references are tricky to handle in Java. How many times did you run your code and obtained NullPointerException as a result? I can tell you that it was a real pain over the time because these scenarios can't be identified at compilation time.
NullPointerException
According to Java 8 Javadoc for NullPointerException, it's thrown when an application attempts to use null in a case where an object is required, such as:
- Calling an instance method of a null object
- Accessing or modifying a field of a null object
- Taking the length of null as if it were an array
- Accessing or modifying the slots of null as if it were an array
- Throwing null as if it were a Throwable value
How did programmers deal with null checks in the past?
As much I can tell, the use of null statement was commonly used by programmers to check for nulls. Let's see an example:
public void printUser (User user) { // Use of null statement if (user != null) { System.out.println(user.getName()); } }
As I mentioned before, this practice was used over the time by programmers however there are other ways to check for nulls without using null statement.
Alternatives to avoid using the null statement
Using Lombok
Using Lombok project, actually helps the programmer to improve code quality and maintain the null contract. Let's see an example
@AllArgsConstructor public class UserWithLombok { @Getter @Setter @NonNull private Long id; @Getter @Setter @NonNull private String name; }
Using @NonNull annotation helps to manage the null contract in methods, fields, variables and parameters. So here, @NonNull makes it clear that id and name properties can't be null and the IDE will alert the programmer with an error at compilation time. Let's see an example:
UserWithLombok user = new UserWithLombok(1L, null) // <--- IDE indicates a compile error because null can't be used.
Use of Objects Utility as Preconditions
There are several programmers that doesn't like to use Lombok to check for nulls for different reasons and prefer to use Preconditions instead. Let's see an example:
@NoArgsConstructor public class UserWithPreconditions { @Getter private Long id; @Getter private String name; public void setId(Long id) { Objects.requireNonNull(id); this.id = id; } public void setName(String name) { Objects.requireNonNull(name, "Name was not present"); this.name = name; } }
The purpose of the code described here is to check all parameters that are non-null as part of contract. As far I can tell, this code is very similar from the presented previously, however using Objects gives some flexibility to customize the error shown to the client.
Use of Optional
Java 8 introduced Optional API and personally this is one of my favorites to check for nulls. Basically, it gives me the flexibility to
- Throw an Exception to handle the null contract in APIs
- Set a default behavior when content is not present
An example of both points can be seen in the following code:
@NoArgsConstructor public class UserWithOptional { @Getter private Long id; @Getter private String name; public void setId(Long id) { Optional.ofNullable(id).orElseThrow(() -> new NoDataProvidedException("Id was not provided")); this.id = id; } public void setName(String name) { Optional.ofNullable(name).orElse("None"); this.name = name; }
}
Conclusion
In this article, we looked how to avoid to check for nulls using different strategies. There is hard to tell which option is the best but it will depend of how the programmer feels more confortable to work with, however what I can say is that nowadays dealing with null statements is something we need to move from and start using built in APIs, even third parties or the ones Java already provides.
Code is available on Github
Crafter @Capgemini (Managing Solution Architect)
10moThere is a small mistake in your last example, the setName method should be implemented like this :
Solutions Architect at dotCMS
4yGreat article, NPE checking is a very important aspect of the app.