Optional vs Null

It’s said that using Optional will solve all the NullPointerExceptions. Is it really true? Or a we just using the Optional as a way to check the null values?

What is the best way to use Optional?

Null Checks

Null checks are like seat belts in a car: if you’re not using them, you’re inviting trouble. Every time you’re handed a variable, you need to ask: “Are you null?” And if you forget to ask, BOOM, NPE strikes again.

public float computePrice(Cart cart) {
   float totalPrice = 0.0f;
   if (cart != null) {
      if (cart.getItems() != null) {
          for (Item item : cart.getItems()) {
              if (item.getUnitPrice() != null) {
                  if (item.getQuantity() != null) {
                      totalPrice += (item.getUnitPrice() * item.getQuantity());
                  }
              }
          }
      }
   }
   return totalPrice;
}

Nevertheless, I’m tired to check them again and again.

So, is this behavior bad? Well, yes and no. On one hand, constantly checking for nulls everywhere can make your code look like it’s preparing for the apocalypse. On the other hand, ignoring null checks is like playing Russian Roulette with your app.

Should you stop using nulls altogether? Let’s be real here: null is a fact of life in Java. Pretending it doesn’t exist won’t make it go away. Instead, you need to understand why a variable might be null in the first place. But we’ll get to that in the conclusion (because every good article needs a cliffhanger).

Theoretical Use of Optional

With the Optional, it’s the way Java says: “Hey, maybe there’s something here, maybe there’s not. But I’ll make you check first.” By wrapping your objects in an Optional, you’re effectively saying, “No nulls allowed!”

At first glance, this seems like a godsend. No more nulls, no more NPEs. But wait, if you’re constantly checking whether an Optional is present, isn’t that just… null checks with extra steps? And if you start calling .get() on an empty Optional, congratulations, you’ve just reinvented the NullPointerException (now it’s called a NoSuchElementException).

public float computePrice(Optional<Cart> cart) {
   float totalPrice = 0.0f;
   if (cart.isPresent()) {
      if (cart.get().getItems().isPresent()) {
          for (Item item : cart.get().getItems()) {
              if (item.getUnitPrice().isPresent()) {
                  if (item.getQuantity().isPresent()) {
                      totalPrice += (item.getUnitPrice().get() * item.getQuantity().get());
                  }
              }
          }
      }
   }
   return totalPrice;
}

I don’t think I’ve a better code.

So, does Optional really solve the problem? Not by itself. Treating it like a fancy null wrapper misses the point. Let’s move on to how it’s meant to be used.

Real Use of Optional

Here’s where things get interesting. The true power of Optional lies in its ability to embrace functional programming. Instead of obsessing over whether the value is present, you chain methods to elegantly handle the empty case. For example:

public float computePrice(Optional<Cart> cart) {
    return cart.flatMap(c -> c.getItems())
               .map(items -> items.stream()
                                 .mapToDouble(item -> item.getUnitPrice().orElse(0.0f) * 
                                                   item.getQuantity().orElse(0))
                                 .sum())
               .orElse(0.0f);
}

Now it’s better.

Let’s break it down:

  • Using map or flatMap, I read the value inside an Optional;
  • If there is no value inside, I fall into the orElse.

No if-else jungle, no manual checks, no unnecessary drama. Just smooth, functional goodness. Optional is not about avoiding checks; it’s about writing more expressive and maintainable code.

Conclusion

Let’s go back to the million-dollar question: Should you stop using nulls? Not necessarily. Null isn’t the enemy; the problem lies in variables that shouldn’t be null but can be. Instead of treating symptoms with endless null checks or blindly wrapping everything in Optional, focus on designing your code to avoid ambiguity in the first place.

I’ve written another article about how to handle the null correctly, how to effectively use it.

And remember, Optional isn’t a silver bullet. It’s a tool, it’s part of a functional programming approach. So, the next time you’re about to throw a null into your codebase, ask yourself: “Do I need this? Or am I just being lazy?”


Never Miss Another Tech Innovation

Concrete insights and actionable resources delivered straight to your inbox to boost your developer career.

My New ebook, Best Practices To Create A Backend With Spring Boot 3, is available now.

Best practices to create a backend with Spring Boot 3

Leave a comment

Discover more from The Dev World - Sergio Lema

Subscribe now to keep reading and get access to the full archive.

Continue reading