Java Optional and Nullable values
Java Optional and Nullable values

Java Optional and Nullable values

How we can use the Optional class to work with null values in Java.

The Optional Container type

public final class Optional<T> was introduced in Java 1.8; The value assigned to the class may or not be null, you can find out which is the case by using the class method isPresent(), a result of true indicates you have a value assigned while false meant otherwise. This container is an integral part of the streams and functional programming in Java in this short write up I show you how to make use of this container to combat null reference errors.

Elvis before Optional

The Groovy programming language had an operator that was used when navigating Object references to ensure the reference pointed to a valid object. It was proposed to have this operator implemented in Java 1.7 , but this was not done until Java1.8. The operator was also implemented in C#.Net and was named the Elvis Operator; the operator in C# and Java was expected to work the same as in Groovy allowing us to perform operations without fear of the dreaded null pointer reference error, this was ok but as you will see the Optional operator is a more robust option when it comes to working with null reference issues.

What was the issue

If we try to perform operations on a null reference object the operation will result in an error because the object on which we intend to perform the operation does not actually exist,to be clear; a variable being set to Null is not problem in and off itself as this is done at times to initialize the variable prior to use.

Example 1

public class Notes
{
	public static void main( String[] args )
	{	
		Integer MyData = null;
		MyData = ReadSomeValuesAndCalculateTheSum();
		System.out.println(MyData);
	}
	
	private static Integer ReadSomeValuesAndCalculateTheSum()
	{
		Integer acc = null; // Initialized
		acc += 1; //  This will result in a nullpointer exception
		return acc;
	}
}

Example 1 Results in an error

Exception in thread "main" java.lang.NullPointerException
	at net.caribtech.rx.Notes.ReadSomeValuesAndCalculateTheSum(Notes.java:21)
	at net.caribtech.rx.Notes.main(Notes.java:9)

Example 2 with Get method- Using Optional

import java.util.Optional;
public class NotesWOptional
{
	public static void main( String[] args )
	{
		Optional<Integer> MyData = null;
		MyData = ReadSomeValuesAndCalculateTheSum();
		System.out.println(MyData.get());
	}
	
	private static Optional<Integer> ReadSomeValuesAndCalculateTheSum()
	{
		Optional<Integer> acc = Optional.ofNullable(null);
		acc=acc.map(num -> num + 1);
		acc =acc.map(num -> num + 11);
		return acc;
	}
}

.get() After updating the code to use the Optional operator your code may not compile partily cause the result of an optional operation is an Optional so you check out the methods on the object an determied what you needed is to call the .get() method. Once again things don’t go as expected. At this junction it’s time for a quick reminder.

Reminder Things can go wrong if you attempt to use a null referenced value at this point we still don’t know what we have, calling .get() will attempt to extract a your value from the held in the Optional type , if this is a null it will fail as before.

What to do

Determine if you have a null before attempting to extract/operate on the value held.

This can be done by calling .isPresent(); or .isEmpty(); on the variable.

if( MyData.isPresent() )
		{
			System.out.println(MyData.get());
		}
		if( MyData.isEmpty() )
		{
			//Danger Will!
		}		

This is ok , but we can do better, lets update our code to use another method of the Optional container .orElse(<some_other_value>) this method allows us to simplify our code while making it more robust.

Example 2 with orElse method

public class NotesWOptional
{
	public static void main( String[] args )
	{
		Optional<Integer> MyData = Optional.ofNullable(null);
		MyData = ReadSomeValuesAndCalculateTheSum();
		System.out.println(MyData.orElse(0));
	}
	/**
	 * 
	 * @return
	 */
	private static Optional<Integer> ReadSomeValuesAndCalculateTheSum()
	{
		Optional<Integer> acc = Optional.ofNullable(10);
		acc = acc.map(num -> num + 1);
		acc = acc.map(num -> num + 11);
		return acc;
	}
}

Example 2 Using Optional with orElse method- Works as expected. Result 22

Instead of the procedural if then else mechanism we simply instruct the Optional to return a different value if the Optional is empty; we do this by calling the orElse() method with a value we want to have returned in the event of a null reference. Note; there are a number of other methods on the Optional container check out the docks.

Conclusion I decided to do this short write up after a conversation with another developer who stayed why hasn’t Java addressed the null problem. I had recalled this class and took the opportunity do a write up.

References:

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators

https://www.oracle.com/technical-resources/articles/java/java8-optional.html

[Java Optional](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html)