Thursday 12 June 2014

Java 8 - getting rid of the use of nulls

Java 8 will result in a slow revolution in the way Java is programmed.  There are so many new features that have been brought in from functional programming and from other languages.  One of the most powerful in terms of reducing program errors is the Optional class.  This isn't quite Scala's "Optional" but it's still incredibly useful.

Optional is a container for a value and can be considered to be a specialised one-element collection.  The use of generics and type inference in Java 8 means that it can be used pretty much universally as the return value of a method or function that in past Java coding would return either an object or null.

The problem with 'null' is that it's meaningless.  It has no type - it isn't an instance of anything useful: a null value could have come from anywhere.  Optional is typed, so can be used to indicate a typed nothingness!

Here is a method that returns an optional Customer:

public Optional<Customer> findCustomerByName(String name);

Typically in Java to date, it would have been reasonable to return a null value to indicate a search failure.  No longer.  Now code like this can be written:

Optional<Customer> customer = findCustomerByName("Zara");

if(customer.isPresent())
    System.out.println(customer.get()); // get() extracts the value contained in the Optional

This is nice.  The meaning here is explicit, which would not be the case for "customer != null".

But we have only got started.  Using Java 8 lambdas, we can also write this:

customer.ifPresent( cust -> System.out.println(cust));

The value is taken out of the optional and is available within the lambda.

With Java 8 method references, this can be abbreviated further:

customer.ifPresent(System.out::println);

Other methods available with Optional include:

Customer whoToUse = customer.orElse(someoneElse);

use the contained customer if present, otherwise use someoneElse.

Customer cust = customer.orElseThrow(IllegalArgumentException::new);

Throw an exception if the Optional doesn't contain anything.

These are extremely concise compared to what had to be previously written in Java, and the meaning is much clearer.

So, replace setting nulls with Optional.empty() and replace all checking of nulls with the clearer and safer Optional methods - you have nothing to use but NullPointerExceptions!


No comments: