DEV Community

vikneswaran
vikneswaran

Posted on • Edited on

Mitigate Null Pointer Exceptions in Java with Optional class

Null pointer exceptions are quite annoying as every java developer should have faced at least once. As the code grows, handling these null pointer exceptions will become tedious with numerous null checks.

Optional class has been introduced in java 8 to provide a type-level solution for representing optional values instead of using null references. Before java 8 Optional class is the part of google's Guava library.

Let's look into some of the implementations with java.util.Optional class

Creating an empty Object

Empty Optional object can be created by calling empty static method of Optional class.

@Test
public void createEmptyOptional() {
    Optional<String> empty = Optional.empty();
    assertFalse(empty.isPresent());//Also we can use the opposite one empty.isEmpty() from java 10
}

isPresent() will return true only if the object in Optional is not null;

Creating Optional class with objects

Optional class can be created with Optional.of() or Optional.ofNullable() static methods

@Test
public void createOptionalObject() {
    String title = "Optional";
    Optional<String> opt = Optional.ofNullable(title);
    assertTrue(opt.isPresent());

    String title2 = null;
    Optional<String> opt1 = Optional.ofNullable(title2);
    assertFalse(opt1.isPresent());
}

Optional.of(title) will throw NullPointerException if the title was null.

Remove null checks while accessing objects with Optional.ifPresent()

It will enable us to run some code on the wrapped value if the Object wrapped in the Optional is found to be not null.

public void checkOptionalIfPresent() {
    Color color = ColorFactoryProvider.getColor("red");
    Optional<Color> red = Optional.ofNullable(color);
    red.ifPresent(color -> System.out.println(color.getColorCode()));//wrapped code will get executed

    Color empty= null;
    Optional<Color> emptyColor = Optional.ofNullable(empty);
    emptyColor.ifPresent(color -> System.out.println(color.getColorCode()));// wrapped code will not get executed
}

Can you see how the Optional class will allow us to get rid of the null checks so that the wrapped code will not get executed if the object is null?

Accessing the Objects from Optional class

There are various methods which also comes with Optional class.

/* 
Optional.get() 
It returns the wrapped object.
it throws a no such element exception if the wrapped object is null.
*/
@Test
public void getValue(){
  Color color = ColorFactoryProvider.getColor("blue");
  Optional<Color> optionalColor= Optional.ofNullable(color);
  assertEquals(color, optionalColor.get());
}

/*
Optional.orElse()
It is like assigning default value for the object. 
if the wrapped object is null then default value will be returned.
*/
@Test
public void OptionalorElseCheck(){
  Color defaultColor = ColorFactoryProvider.getColor("red");
  Color blue = ColorFactoryProvider.getColor("blue");
  Optional<Color> optionalColor = Optional.ofNullable(blue);
  assertEquals(blue, optionalColor.orElse(defaultColor));

  Color empty = null;
  Optional<Color> emptyColor = Optional.ofNullable(empty);
  assertEquals(defaultColor, emptyColor.orElse(defaultColor));
}

Also we have some other useful methods
Optional.orElseGet() - which is similar to orElse() the only difference is it takes a supplier functional interface as input and invokes only if the wrapper object in Optional is null.

Optional.orElseThrow() - which is similar to orElse() the only difference is it take Exception Object as input and it will throw given exception if the wrapped object in Optional is null.

So start refactoring your code with Optional class which provides the best practices for handling null in java.

For more detailed reference check the official documentation

Top comments (4)

Collapse
 
michelemauro profile image
michelemauro

The most important part is that using the Optional you are explicilty telling the user of your API that they may receive a value, or they may not. And both cases are clearly usable and testable.

Collapse
 
elmuerte profile image
Michiel Hendriks

That's basically the only use I see for using Optional, clear communication that you might not get anything.
Because for the rest it is just as unsafe.

Collapse
 
brianverm profile image
Brian Vermeer 🧑🏼‍🎓🧑🏼‍💻

Be aware of the differences between orElse() and orElseGet()
They may look similar but do serve a different purpose.
dev.to/brianverm/optional-what-els...

Collapse
 
gabriela profile image
Gabi

I am starting to use and like of course Optional in my code and you are right, the spiral down of null checks in java could be ridiculous.