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.
Consider the following code :
public void setValue(ValueWrapper valueWrapper) {
if (anotherValueWrapper == null) {
anotherValueWrapper = new AnotherValueWrapper();
}
anotherValueWrapper.setValue(valueWrapper == null ? null : valueWrapper.getValue());
}
The facts :
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.
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 ?
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With