Guide To Java Optional : Part 1

Mrinal Gupta
Nerd For Tech
Published in
5 min readNov 18, 2023

In Java World, nobody is new to the null pointer exception. The zeal of expecting a result for a query but the pain of getting a null. Java 8 gave us Optional to handle these null pointer exceptions. But is that it? A whole class to handle null pointer! It can actully do much more than we imagine. So. let’s deep dive into everything about optional.

What is Optional?

Introduced in Java 8, it is intended to provide a limited mechanism for library method return types where there is a clear need to represnt “no result”, and where using null for that is overwhelmingly likely to cause errors.

It can be in two states:

  • contains a non null reference to a T (generic type); also called “present”
  • is empty: also called “absent” (also, let’s stop saying null when we talk about optional)

Optional itself is a reference type, and can be null. But, do not ever, ever, use null for an Optional varibale or return value. (let’s say this is a mandatory thing)

Why do I need Optional?

Consider this pseudo code in Java streams:

return employeeList.stream()
.filter(find me employee with age greater than 56)
.getName(); // throws NullPointerException if no employee is found

What happens if no element matches the predicate, the search would return null right. But what if you intend to do further things when result is found? Can’t do them right, because there is no result matching the predicate. What you have is null.

Maybe, we can compare the result with null and if it is not null then we can do those things that we intended to do and if it is null, let’s handle it gracefully saying we did not find anything or do something else.

This is how your pseduocode would look like loosely:

Employee employee = employeeList.stream()
.filter(find me employee with age greater than 56);
return employee != null ? employee.getName() : "DO Something else";
// messy code
// why am I writing streams if I want my code to be this messy
// everytime I have to remember to make a null check, what the hell?
// I am crying, do something
// I will switch to python maybe

wait, wait!!

Optional is here for rescue. Let’s decode the Optional.

Since Optional is refernece type, it can be returned. See below code for example:

Optional<Employee> emp = emplList.stream()
.filter(emp -> emp.getID() == empID)
.findFirst();

findFirst() will return an Optional of type Employee. but did we want that? No, we wanted Employee. So, the next question is how to get the Employee out of optional.

The get() Method

We can do this by get() method:

// continuing after above code
Employee employee = emp.get();

This is the official documentation of get() method.

Official documentation of get() method

If you have looked at it closely, you will notice that for the value null(empty Optional), it throws NoSuchElementException. Bravo! We managed to have other exception in place of NullPointerException (sarcasm). So, as a rule

Never use get() unless you can prove that the optional is present.

How to do that? Let’s see!

isPresent() Method

isPresent() returns a boolean. If the value is there it returns true, else if the optional is empty it returns false.

Employee employee = emp.isPresent() ? emp.get() : "DO something";

This is safeer than get() but it is hardly any better than checking for null. Also, this creates a bad habit in programmers to test with isPresent() before get(). We need to find alternatives to isPresent() and get().

orElse() Method and Its Variations

It gets (get()) the wrapped value inside Optional if it is present (isPresent) and its argument otherwise. For Example:

String nullName = null;
String name = Optional.ofNullable(nullName).orElse("john");

By the way, ofNullable() is used to create Optional when you expect a null value. And, orElse with return the value nullName is it is non null else it will return it’s argument “john”.

This is the official documentation of orElse() method. Notice, it would return other of generic type T is the value is not present. T should be same as Optional<T>. You cannot have an optional of type String and returns a deafult value of type Intger from orElse(). Also, notice one more thing, if you pass null as other, orElse() wil return null.

orElseGet() Method

Returns the value if present, or else gets a defaultn value by calling a supplier.

Optional<Data> opt = ...
Data data = opt.orElseGet(Data::new);

Let me simplify one thing for you here:

orElse(default_value)
orElseGet(supplier)

Notice that orElse() already has a default value to provide if the Optional is not present but orElseGet() would have to call the supplier so creation of deafult value is lazy in case of orElseGet() when the optional is absent.

Conclusion

We saw a lot of things in this article and really wanted to conclude everything here in this article. But it would be unfair to Optional. We still have a lot to go like, what if we really want to throw an exception(orElseThrows()), what if we want to transform optional (map() and filter() in optional()), we saw findFirst() are there other similar methods that return optional? what are some bad uses of optional?

One brillliant thing about optional is you can go from not using it to overusing it, we will see those scenarios as well. We will also see some show off stuff like is Optional Serializable? we will also see some methods which were introduced in java 9.But for all that stay tuned!

Watch this space for link of next article and best is to follow me!

Happy coding!!

--

--

Mrinal Gupta
Nerd For Tech

Software Developer on weekdays and A reading enthusiast on weekends. Beethoven’s silence and Chopin’s minute waltz intrigue me.