Handling/Avoiding Null’s in Java using Guava versus Scala

SHARE & COMMENT :

There was a discussion about nulls in the latest episode of JavaPosse. Having been inspired from that discussion and with an urge to check out Google Guava library, I came across a way to handle Null’s in Guava which is very similar to the way Scala handles.

also read:

Lets consider the Person class which is defined as:

class Person{
  String firstName;
  String lastName;
  Person(String fName, String lName){
    firstName = fName;
    lastName = lName;
  }

  @Override
  public boolean equals(Object pObj){
    if ( pObj == null){
      return false;
    }
    Person p = (Person)pObj;
    return (firstName.equals(p.firstName) &&
            lastName.equals(p.lastName));
  }

  @Override
  public String toString(){
    return firstName+" "+lastName;
  }
}

Consider a method conditionalPersonGenerator which constructs a Person object based on some condition, and the method can also return null in some cases. Let’s create a hypothetical condition where it returns a Person object if the number passed to the method is even, null otherwise.

private static Person conditionalPersonGenerator
    (int number){
  if ( number%2 == 0){
    return new Person("firstName","lastName");
  }
  else{
    return null;
  }
}

The method which invokes conditionalPersonGenerator should make it a point to check for null values being returned. There are a lot of cases where its not clearly known that the method can return a null, or say some collection can contain null elements. So its a responsibility of the caller to make sure that the values he gets from the method invocations are not null and there are no NullPointerExceptions being thrown frequently.

A ideal way is to not return null at all, for example a method which is supposed to return a List can return an empty List instead of returning null. But not all would care for what they are returning. In Design By Contract the methods can use Preconditions and Postconditions to include such sanity checks, but Java doesn’t support Design By Contract out of the box.

There has been good support for handling null references in newer languages on the JVM like Scala, Groovy, Kotlin and others. There have been attempts to get such features into Java language by means of JSR 308, Apache Commons API, Google Guava API and others.

The null handling which Guava provides is very close to the one in Scala- they try to avoid the use of null altogether. Sir C. A. R. Hoare who invented the “null” reference calls it as a billing dollar mistake. Lets see how we can use Guava to avoid null and compare it with the support provided by Scala.

Avoiding nulls in Java using Google Guava

Guava provides a class called Optional which wraps some value. It either contains some value or doesn’t contain any value. But it never contains a null. There are a few useful methods to construct the Optional instance.

  • absent()- This creates an Optional instance with no value in it. This can be used in place of the “null” keyword/reference.
  • of()- This creates an Optional instance with a value wrapped in it.
  • fromNullable()- This performs the functionality of both absent() and or(). When the argument passed to this method is null, it invokes absent() else it invokes or()

There are a few changes to be done in our conditionalPersonGenerator method:

  • In our conditionalPersonGenerator method, instead of returning Person instance, we will return an instance of Optional.
  • In place of returning null we will return Optional.absent()
  • In place of returning new Person, we will return Optional.of(new Person(arg1,arg2))
private static Optional<Person> conditionalPersonGenerator
    (int number){
  if ( number%2 == 0){
    return Optional.of(new Person("firstName","lastName"));
  }
  else{
    return Optional.absent();
  }
}

Optional class provides some methods to retrieve the its contents:

  • get()- This returns the contents in the Optional instance. There has to be some value contained in the instance, otherwise it throws IllegalStateException.
  • or(defaultValue)- This returns the contents of the Optional instance and if it doesn’t have any contents, it returns the default value passed to the method.
  • orNull()- This returns its contents or null if it has not contents.
  • .

One can even use isPresent() to check if the instance has some value within it and then use get() to retrieve it.
Lets see how these methods can be used

public class GuavaTest {
  public static void main(String[] args) {
    //Prints Default
    System.out.println(conditionalPersonGenerator(1)
        .or(new Person("Default","Default"))
        .firstName);

    //Prints firstName
    System.out.println(conditionalPersonGenerator(2)
        .or(new Person("Default","Default"))
        .firstName);

  }

  private static Optional<Person> conditionalPersonGenerator
      (int number){
    if ( number%2 == 0){
      return Optional.of(
        new Person("firstName","lastName"));
    }
    else{
      return Optional.absent();
    }
  }
}

Avoiding nulls in Scala using Option, Some, None

The above approach is very similar to the one in Scala. Scala provides a Option class along with its 2 subclasses None and Some.
Some represents an existing value, whereas None indicates non-existent values.

The Person class definition in accordance with Scala syntax would be:

class Person {
  def this(fName: String, lName: String) {
    this()
    firstName = fName
    lastName = lName
  }

  override def equals(pObj: Any): Boolean = {
    if (pObj == null) {
      return false
    }
    var p: Person = pObj.asInstanceOf[Person]
    return ((firstName == p.firstName) && (lastName == p.lastName))
  }

  override def toString: String = {
    return firstName + " " + lastName
  }

  private var firstName: String = null
  private var lastName: String = null
}

The conditionalPersonGenerator method is defined as:

 def conditionalPersonGenerator(number:Int):Option[Person]={
    if (number % 2 == 0){
      return new Some[Person](new Person("ScalaFirst","ScalaLast"))

    }else{
      return None
    }
 }

Note the use of new Some to create an instance with some value and just None for representing that the value has nothing in it. The “None” is not a class but a Singleton object, and hence it wasn’t necessary to create an instance of None. This is very similar to the approach adopted by Guava.

Lets see the complete scala code where this is being used

object OptionTest{
  def main(args: Array[String]) = {
    //Prints Default
    println(conditionalPersonGenerator(1).getOrElse(new Person("Default","Default")))
    //Prints ScalaFirst
    println(conditionalPersonGenerator(2).getOrElse(new Person("Default","Default")))

  }

    def conditionalPersonGenerator(number:Int):Option[Person]={
      if (number % 2 == 0){
        return new Some[Person](new Person("ScalaFirst","ScalaLast"))

      }else{
        return None
      }
    }
}

class Person {
  def this(fName: String, lName: String) {
    this()
    firstName = fName
    lastName = lName
  }

  override def equals(pObj: Any): Boolean = {
    if (pObj == null) {
      return false
    }
    var p: Person = pObj.asInstanceOf[Person]
    return ((firstName == p.firstName) && (lastName == p.lastName))
  }

  override def toString: String = {
    return firstName + " " + lastName
  }

  private var firstName: String = null
  private var lastName: String = null
}

In place of using or(defaultValue) method, in Scala we make use of getOrElse(defaultValue) method. In Guava use of get() on Optional with no value present in it would throw IllegalStateException, where as in the same context use of get() on Option throws NoSuchElementException.

Comments

comments

About Mohamed Sanaulla

In his day job he works on developing enterprise applications using ADF. He is also the moderator of JavaRanch forums and an avid blogger.

Trackbacks

  1. [...] this out if you are curious about Some and None. The idea is simple- in apply method take the parameter [...]

  2. JavaPins says:

    Handling/Avoiding Null’s in Java using Guava versus Scala…

    Thank you for submitting this cool story – Trackback from JavaPins…

Speak Your Mind

*

Close
Please support the site
By clicking any of these buttons you help our site to get better