В разделе Оценка времени выполнения Ссылки на методы Спецификации языка Java упоминается, что:
Во время выполнения оценка выражения ссылки на метод аналогична оценке выражения создания экземпляра класса, поскольку обычное завершение создает ссылку на объект. Оценка выражения ссылки на метод отличается от вызова самого метода.
Во-первых, если выражение ссылки на метод начинается с ExpressionName или Primary, оценивается это подвыражение. Если подвыражение оценивается как
null
, возникаетNullPointerException
, и выражение ссылки на метод завершается внезапно. Если подвыражение завершается внезапно, выражение ссылки на метод завершается внезапно по той же причине.
И ExpressionName и Primary определены в синтаксис выражения ссылки на метод:
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? Если да, может ли кто-нибудь более подробно объяснить значение вышеприведенной цитаты или привести пример, где это могло бы произойти?
p::getName
должна была вызвать NPE. Думаю, они не добавляли эту проверку, поэтому NPE откладывается до фактического использования. См. Соответствующий JDK-8131323. - person Andreas   schedule 14.12.2017