The Mistry of Optional and NullPointerException

The Mistry of Optional and NullPointerException


1






Rahul Kumar (@rahul)

We often deal with a well-known NullPointerException which is almost common across high-level programming languages. NullPointerException sometimes leads to an entire server crash 💥. We used to add a null check but it's pretty common that human makes mistake. In this blog, we'll learn how can we minimise those human mistakes by using Optional.

In Nutshell

Java's Optional enforces programmers to check nullability before accessing the object, which reduces the chance of NullPointerException. It was introduced in 2014 to allow developers to represent the empty state. In simple words, Optional is a container for the object, which has two states empty or present. 

Terror of NullPointerException!

NullPointerException is a very common exception that can be caused in our code or any library, package, or tool that we are using. Then there is no other way than debugging for hours/days. You can check this StackOverFlow link to understand the commonality of NullPointerException

Below is a quick snapshot of the above link!

What actually is Java Optional?

Java's Optional is a container for Object and just like any other real-life container it can have items or it can be empty. 

Consider the below user class which has a single property name along with getter/setter.

User Class

      class User {
  private String name;

  public String getName() {
    return name;
  }

  public User setName(String name) {
    this.name = name;
    return this;
  }
}
    

Consider the below Main class which is creating and accessing the user. 

      public class DsaByteOptionalDemo {
  // simulate a real world scenario of database which can have user or can't
  // isUserPresentInDB will return true for 50% and false for another 50%
  private static boolean isUserPresentInDB() {
    return Math.random() < 0.5;
  }

  private static User getUser() {
    if (isUserPresentInDB()) {
      return new User().setName("@dsabyte");
    }

    return null;
  }

  public static void main(String[] args) {
    User user = getUser();
    System.out.println("User: " + user.getName());
  }
}
    

It's clear that the getUser method can return null 50% of the time and we'll get a NullPointerException for accessing user.getName().  We can add a null check before accessing the user name in order to avoid NullPointerException

        public static void main(String[] args) {
    User user = getUser();
    
    if(user == null){
        return;
    }
    
    System.out.println("User: " + user.getName());
  }
    

Adding a null check was a great solution but it's pretty common that we can forget to add a null check which can crash our servers. It's not possible for anyone to make sure that null is always checked 100% of the time.

 Here is a proof that programmers are making mistakes.  

Let's assume that we are using a method getProducts of a popular library Ecom that returns an array of products. The documentation mentioned that the method will always return an array, if there is no such product exists then the method will return an empty array. 

Ecom is an E-Commerce library

Before using Optional

      // here is how are we using Ecom.getProducts() in our code
public int getProductsCount(){
    return Ecom.getProducts().length;
}  

    

getProductsCount method calls Ecom.getProducts() to get the array of products and calls .length to get the count. Since it was mentioned in the documentation that Ecom.getProducts() will always return an array regardless of whether any product is present or not.

Suppose, due to some reason, Ecom.getProducts() started returning null and Ecom.getProducts().length started throwing NullPointerException now.  Since it was not handled by us our application started crashing. 

Now, think that Ecom.getProducts() is returning Optional instead of an array and the above code would looks like. 

After using Optional

      // here is how are we using Ecom.getProducts() in our code
public int getProductsCount(){
    Optional<List<Product>> fetchedProducts = Ecom.getProducts();
    if(fetchedProducts.isEmpty()){
          return 0;
    }
    return fetchedProducts.get().length;
}  

    

Just think about how the above code is modified to handle unintentional exceptions in a much cleaner way. Optional forcing programmers to check about the state before accessing them. This check ensures that we never run into NullPointerException

Advantage of Optional

  • Avoiding NullPointerException
  • Improved Code Readability
  • Explicit handling of absence
  • Reduction of boilerplate code
  • Encourage defensive programming

Disadvantage of Optional

  • Verbosity in some cases
  • Null inside Optional
  • Potential abstraction misuse
  • Limited serialization support

Add a thoughtful comment...

✨ Explore more tech insights and coding wonders with @dsabyte! Your journey in innovation has just begun. Keep learning, keep sharing, and let's continue to code a brighter future together. Happy exploring! 🚀❤️

  • #java
  • #programming
  • #optional
  • #nullpointerexception
  • #null
  • #null-pointer

Subscribe to our newsletter.

Join the "News Later" community by entering your email. It's quick, it's easy, and it's your key to unlocking future tech revelations.

Weekly Updates

Every week, we curate and deliver a collection of articles, blogs and chapters directly to your inbox. Stay informed, stay inspired, and stay ahead in the fast-paced world of technology.

No spam

Rest assured, we won't clutter your inbox with unnecessary emails. No spam, only meaningful insights, and valuable content designed to elevate your tech experience.

© 2024 @dsabyte. All rights reserved