January 9, 2022

Watchout for NullPointerException while using method reference in Java, and Learn how you can fix it.

As a Java developer, I love to use method reference whenever I get an opportunity to do it.

But, most of us don’t know that we can get NullPointerException , if we are not careful.

Let us see an example.

I have a function, which takes a supplier, and it prints the value supplied by the supplier.

static void test(Supplier<String> supplier){
    System.out.println(supplier.get());
}

I have a record Person, which has one field name.

record Person(String name){}

Now, I am going to create an object of Person class, and pass the name() function in the form of method reference to test(), as an implementation of Supplier.

Person person = new Person("Anurag") ;
test(person::name);

If I copy above code in a main() method, and run it. It will print ‘Anurag’ as expected.

What If, at runtime the person object was null?

To handle that, we can write a new implementation for test() function, where we only call supplier.get(), if the person object is not null.

static void test(final Person person, Supplier<String> supplier){
    System.out.println(person == null ? "" : supplier.get());
}

Will it work ??

No, It won’t work.. We are still going to get NullPointerException.

Person personNull = null;
test(personNull::name);
test(personNull, personNull::name);

A call to test() function, with safe implementation throws NullPointerException, as well

But.Why??

Because, Java does ‘Object.requireNonNull()’ over the passed object i.e person or personNull, before invoking name() on the object.

So, How can we get around this, and make sure, our safe test() function, which has ability to check for null-case over the object works.

We can use lambda expression over here.

static void test(final Person person, Supplier<String> supplier){
    System.out.println(person == null ? "person is null" : supplier.get());
}

test(personNull, () -> personNull.name());

Now, I will get an output of ‘person is null‘, if the passed object ‘person‘ is Null. This is a way you can work around.

Or we can write an implementation of test() function using ‘Function’ interface.

static void test(final Person person, Function<Person, String> function){
    System.out.println(person == null ? "person is null" : function.apply(person));
}

And, we can call the above function like this.

Person person = new Person("Anurag") ;
Person personNull = null;

test(person, (p) -> p.name());

test(personNull, (p) -> p.name());

To reduce boiler plate code, we can refactor the above code to create one function object from (p) -> p.name().

These are two ways, that I know of, can handle the NullPointerException while using method-reference.