w sekcji Run-Time Evaluation of Method References z języka Java Specification, wspomniano, że:Runtime oceny wyrażeń w metodzie Java odwołuje
W czasie wykonywania oceny wyrażenia referencyjnego metoda jest podobna do oceny z tworzenia instancji klasy wyrażenie, o ile zwykłe wypełnienie tworzy odniesienie do obiektu. Ocena wyrażenia referencyjnego metody różni się od wywołania samej metody.
pierwsze, jeśli ekspresja Referencyjny Sposób rozpoczyna się ExpressionName lub podstawowej to wyrażenie zostanie ocenione. Jeśli podwyrażenie zostanie ocenione na
null
, zostanie podniesiona wartośćNullPointerException
, a wyrażenie odwołania do metody zakończy się nagle. Jeśli podwyrażenie zakończy się nagle, wyrażenie referencyjne metody kończy się nagle z tego samego powodu.
I ExpressionName i Podstawowa są zdefiniowane w 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
byłem zainteresowany przez podświetlonej części i chciał przetestować wspomniany zachowanie za pomocą poniższego kodu:
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";
}
}
}
Jednak linia foo(p::getName)
nie rzucać NullPointerException. Czy nie rozumiem powyższego cytatu z JLS? Jeśli tak, czy ktoś mógłby wyjaśnić więcej znaczenia powyższej oferty lub podać przykład, gdzie by to miało miejsce?
interesujący, bym spodziewałem się rzucać rzeczywiście wyjątek i Próbuję zmienić go do wyrażenia lambda (myśląc, że to na pewno się zepsuje), ale tak się nie stało. dobre pytanie – Eugene
Zgadzam się, zgodnie ze specyfikacją, odwołanie do metody 'p :: getName' powinno zawierać NPE. Zgadnij, że nie dodali tej walidacji, więc NPE jest odroczone do momentu rzeczywistego użycia. Zobacz powiązane [JDK-8131323] (https://bugs.openjdk.java.net/browse/JDK-8131323). – Andreas
Istnieje [wcześniejsze pytanie na ten temat] (https://stackoverflow.com/q/37681625/2711488), jednak brak odnośnika do raportu w narzędziu do śledzenia błędów Eclipse. Jestem cicho pewien, widziałem jeden w przeszłości ... – Holger