Java 方法引用中表达式的运行时评估

Runtime evaluation of expressions in Java method references

在 Java 语言规范的 Run-Time Evaluation of Method References 节中,提到:

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.

ExpressionNamePrimary定义在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 

我对突出显示的部分很感兴趣,想使用以下代码测试上述行为:

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";
        }
    }
}

但是,行 foo(p::getName) 不会抛出 NullPointerException。我是否误解了 JLS 的上述引述?如果是的话,有人能解释一下上面引述的意思或者举个例子吗?

天哪!那是一个 eclipse bug (ECJ),它因 javac/java 而失败(我在示例中尝试了 9,但同样的事情发生在 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)