Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Little puzzle : why null pointer exception?

Introduction

I was stucked to this problem few minutes. So, it will probably help someone else and it's a fun bug. But solving the first question sent me to another question.


First puzzle question :

Consider the following code :

public void setValue(ValueWrapper valueWrapper) {

        if (anotherValueWrapper == null) {
            anotherValueWrapper = new AnotherValueWrapper();
        }

        anotherValueWrapper.setValue(valueWrapper == null ? null : valueWrapper.getValue());
    }

The facts :

  • This code compiles
  • getter and setter are standards (no more code than returning the field or set it)

The problem

During execution, there is one case where the code fails and return a null pointer exception.

The first puzzle question is : when this code can result into a NullPointerException ?

Do not look at the second question, because it's a spoiler if you haven't found the first question.


Second question

Ok, you find it (or maybe not) : the problem is when AnotherValueWrapper is written like this :

public class AnotherValueWrapper {
  private long value;

  public long getValue() { return value; }

  public void setValue(long value) { this.value = value; }
}

and ValueWrapper:

public class ValueWrapper {
  private Long value;

  public Long getValue() { return value; }

  public void setValue(Long value) { this.value = value; }
}

Here come the second question :

if I write :

anotherValueWrapper.setValue(null);

or

anotherValueWrapper.setValue(valueWrapper == null ? "test": valueWrapper.getValue());

if does not compile due to the fact that anotherValueWrapper.setValue takes a primitive (long) and not a Long (object).

BUT this code compiles :

anotherValueWrapper.setValue(valueWrapper == null ? null : valueWrapper.getValue());

Why ?

like image 422
Jerome Cance Avatar asked May 07 '26 16:05

Jerome Cance


2 Answers

With

anotherValueWrapper.setValue(valueWrapper == null ? null : valueWrapper.getValue());

null is really of type Long which tries to autobox to long and therefore throws a null pointer exception

like image 128
Chris Knight Avatar answered May 09 '26 04:05

Chris Knight


When you do setValue(null) or setValue("test"), it's explicitly passing in an Object and a String class and they don't match the primitive type long.

However, passing in the object type Long is ok because of Java's autoboxing feature, which automatically converts between the primitive type and its Object wrapper. When you pass in the Long object into anotherValueWrapper's setValue() method, it executes the Long's longValue() method underneath the hood and it would result in NullPointerException if the Long object is null.

like image 29
Michelle Avatar answered May 09 '26 04:05

Michelle