Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Runtime evaluation of expressions in Java method references

In section Run-Time Evaluation of Method References of the Java Language Specification, it is mentioned that:

At run time, evaluation of a method reference expression is similar to evaluation of a class instance creation expression, insofar as normal completion produces a reference to an object. Evaluation of a method reference expression is distinct from invocation of the method itself.

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.

And ExpressionName and Primary are defined in the method reference expression syntax:

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 by the highlighted part and wanted to test the mentioned behavior using the below code:

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 line foo(p::getName) does not throw a NullPointerException. Am I misunderstanding the above quote from the JLS? If yes, could someone explain more the meaning of the above quote or give an example where it would occur?

like image 252
M A Avatar asked Dec 14 '17 15:12

M A


People also ask

What are reference methods in Java?

There are four kinds of method references: Static methods. Instance methods of particular objects. Instance methods of an arbitrary object of a particular type.

Which is better lambda or method reference?

I prefer method references for multiple-argument lambdas, and sometimes to emphasize that the lambda is only about a single method call. There is less to go wrong with a method reference: you might misspell the argument at use site, accidentally referring to a variable from outer scope, etc.

What is difference between lambda expression and method reference in Java?

Lambda expression is an anonymous method (method without a name) that has used to provide the inline implementation of a method defined by the functional interface while a method reference is similar to a lambda expression that refers a method without executing it.


1 Answers

Oh darn! That's an eclipse bug (ECJ), it fails with javac/java (I've tried 9 here in the example, but 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)
like image 191
Eugene Avatar answered Oct 10 '22 20:10

Eugene