If you use Java as your primary programming language, you've come across a NullPointerException at some point in your life. At a very high level, a NullPointerException is a RuntimeException that happens when you try to access a variable, but this variable is pointing to no object, and it's referring to nothing (or null).
Take a look at the code snippet below:
public class Country {
public static void main(String[] args) {
String[] countries = new String[5];
String asianCountry = countries[3].toUpperCase();
System.out.println(asianCountry);
}
}
What we get is:
Exception in thread "main" java.lang.NullPointerException
at Country.main(Country.java:7)
We're getting a NullPointerException because we have a String array of countries, and we're trying to access its third element, which is null.
There are some alternative ways that we can use to handle the NullPointerException, such as surrounding the code in a try/catch block (like in exampleOne) or if statements (like in exampleTwo).
public class Country {
public static void main(String[] args) {
String country = "India";
exampleOne(null);
exampleTwo(null);
}
static void exampleOne(String country){
try {
System.out.println("Printing the country using try/catch: " + country.toUpperCase());
} catch(NullPointerException e){
System.out.println("Throwing a NullPointerException");
}
}
static void exampleTwo(String country){
if(country != null){
System.out.println("Printing the country using IF/ELSE statement: " + country.toUpperCase());
} else {
System.out.println("There is no such country");
}
}
}
Outcome:
Throwing a NullPointerException
There is no such country
But this way, we're just making the code unpleasant to read. Plus, what if we have to check more data? The code would become more verbose.
Java 8 has introduced the Optional class in the _ Java.util_ package, which functions like a box that may or may not contain null values.
What are the benefits of using this class?
- At runtime, we won't get a NullPointerException. 🙌🏾
- We don't have to carry out null checks. 🙌🏾
- We reduce boilerplate code. 🙌🏾
- We get to develop tidier APIs. 🙌🏾
The example above can be rewritten like this using the Optional class.
import java.util.Optional;
public class Country {
public static void main(String[] args) {
String[] countries = new String[5];
Optional<String> checkCountry = Optional.ofNullable(countries[3]);
if(checkCountry.isPresent()){
String country = countries[3].toUpperCase();
System.out.println(country);
} else {
System.out.println("The country is null");
}
}
}
- We created a String Optional that corresponds to the third country in the string array.
- The ofNullable() method returns an Optional with that value if it exists. Otherwise, it returns an empty Optional.
- In the IF/ELSE block, we're seeing if the country is present in the Optional or not. If it is, we print out the country in uppercase. Otherwise, we print a message to say that "The country is null."
Since we haven't initialized the String array, the output would be:
The country is null
Otherwise, we can initialize the variable like here:
import java.util.Optional;
public class Country {
public static void main(String[] args) {
String[] countries = new String[5];
countries[3] = "India";
Optional<String> checkCountry = Optional.ofNullable(countries[3]);
if(checkCountry.isPresent()){
String country = countries[3].toUpperCase();
System.out.println(country);
} else {
System.out.println("The country is null");
}
}
}
And the output would be:
INDIA
When is it best to use the Optional class?
✅ At return type
✅ Combined with Streams
When should we avoid using the Optional class?
❌We shouldn't use it as a private field because it's not serializable (meaning that we wouldn't be able to transform that object into a format that we can store in the memory).
❌ In method parameters or constructors: we would make the code more complicated to read.
It's critical to highlight that Optional is not a way to avoid all types of null checks. For example, you'll still need to think about the inputs taken in constructors and methods.
I hope that you've found this helpful. Optional is an exciting addition, but be careful not to overuse it as it may potentially kill off its benefits! 😊