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.
和ExpressionName和Primary定义在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)
在 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
, aNullPointerException
is raised, and the method reference expression completes abruptly. If the subexpression completes abruptly, the method reference expression completes abruptly for the same reason.
和ExpressionName和Primary定义在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)