Estimating the runtime of expressions in Java method references

The section Estimating the execution time of method references in the Java Language Specification mentions that:

At run time, evaluating a method reference expression is similar to evaluating an instance of a class instance because normal termination creates a reference to the object. Evaluating a method reference expression is different from invoking the method itself.

First, if a method reference expression begins with ExpressionName or Primary, this subexpression is evaluated. If the subexpression evaluates to null , a NullPointerException , and the method reference expression terminates abruptly. If the subexpression completes abruptly, the method reference expression terminates abruptly for the same reason.

Both ExpressionName and Primary are defined in the syntax of the link expression:

 MethodReference: 
  ExpressionName :: [TypeArguments] Identifier ReferenceType :: [TypeArguments] Identifier Primary :: [TypeArguments] Identifier super :: [TypeArguments] Identifier TypeName . super :: [TypeArguments] Identifier ClassType :: [TypeArguments] new ArrayType :: new 

I was interested in the highlighted part and wanted to test the mentioned behavior using the code below:

 public class Test { public static void main(String[] args) { System.out.println("Testing..."); final Person p = null; foo(p::getName); // I was expecting an NPE here } private static void foo(Supplier<String> supplier) { System.out.println(supplier); // supplier.get(); // uncommenting this causes an NPE, but not when evaluating // the method reference, but rather when the method is invoked. } static class Person { String getName() { return "x"; } } } 

However, the string foo(p::getName) does not throw a NullPointerException. Do I misunderstand the above quote from JLS? If so, can someone explain more of the meaning of the above quote or give an example where this will happen?

+8
java eclipse java-8 method-reference
source share
1 answer

Oh shit! What is the eclipse ( ECJ ) error , it fails with javac/java (I tried 9 here in the example, but the same thing happens in 8):

  Testing... Exception in thread "main" java.lang.NullPointerException at java.base/java.util.Objects.requireNonNull(Objects.java:221) at org.eugene.so.DeleteMe.main(DeleteMe.java:11) 
+7
source share

All Articles