Why does this throw a NullPointerException? The docs for Java 8 state that: "If a value is present, invoke the specified consumer with the value, otherwise do nothing."
public static void main(String[] args) {
List<String> uninitialisedList = getList();
Optional<String> opt = Optional.empty();
opt.ifPresent(uninitialisedList::add);
}
private static List<String> getList() {
return null;
}
This is because the method reference expression
uninitialisedList::addthrows aNullPointerExceptionwhenuninitialisedListis null. From the Java Language Specification:Even though the
addmethod is not actually called (as the documentation forifPresentsays, it will not be called in this case), the method reference expression still needs to be evaluated before callingifPresent, because it is an argument ofifPresent. And evaluating the method reference expression is when theNullPointerExceptionis thrown.Intuitively,
uninitialisedList::addis a "reference" to theaddmethod onuninitialisedList. IfuninitialisedListis null, there is no such method, so it is natural for an exception to be thrown.Compare this with a lambda expression:
Evaluating the lambda expression does not throw a
NullPointerException(see the relevant section in the JLS). It just creates a new object implementing the functional interface. As long as the lambda body is not executed, it's all fine.