There are a bunch of questions where people have realized that creating a method reference with an expression that evaluates to a null
value will result in a NullPointerException
. As an example:
String s = null;
Supplier<char[]> fun = s::toCharArray;
This is due to the following paragraph in the java specification:
First, if the method reference expression begins with an ExpressionName or a Primary, this subexpression is evaluated. If the subexpression evaluates to null, a NullPointerException is raised, and the method reference expression completes abruptly. If the subexpression completes abruptly, the method reference expression completes abruptly for the same reason.
Now my question is, does anyone happen to know what the reason behind this (based on the many confused questions) counterintuitive specification was/is?
The only thing that comes to my mind is that in the following case it is hard to accurately report the error of the NullPointerException
if it happens during the evaluation of the Supplier
:
public static char[] callback(Supplier<char[]> supplier) {
return supplier.get();
}
public static void main(String[] args) {
String s = null;
callback(s::toCharArray);
}
The reason here is the fact that when you are creating non static method reference, it must have access to this
. When you are trying to create reference to null object, there is no this
anywhere, that is why it should fail on this step, instead of failing somewhere further in the code when it is used for the first time.
Imagine in one place you get the object, save it's method reference somewhere, and than use it in completely different part of code. You'll get an NPE not in the place where the error was made, but many lines of code away.
Because the Java compiler is not a linter/logic checker.
Nothing in Java prevents you to trigger a NPE by dereferencing null
.
For example Java doesn't prevent you from doing :
String s = null;
s.toString();
That is right before Java 8 and that is right still today for method references.
The paragraph you quote details simply how at runtime the JVM handles this point for method references that is that if a part of the method reference evaluation fails, the whole evaluation fails.
Note that in your actual example your IDE will probably emit a warning because the scope of the potential bug is very tight.
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