Czy to błąd lub funkcja?java 8 Opcjonalna mapa() rzut NPE z odniesieniem do funkcji, ale nie z pełną składnią lambda
Poniżej powiedzie się z NPE
Function<String, String> f = null;
Optional.<String>empty().map(f).orElse(null);
Ale nie
Function<String, String> f = null;
Optional.<String>empty().map(value -> f.apply(value)).orElse(null);
IntelliJ na przykład sugerowałaby zastąpić drugie wyrażenie przez pierwszy za równoważne, co dla mnie sens, aż do teraz.
Powodem takiego zachowania jest realizacja Optional#map()
:
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
// check happens before the branching
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
Zamiast tego, jeśli map()
został zrealizowany przy:
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
if (!isPresent())
return empty();
else {
// the check happens only when relevant
Objects.requireNonNull(mapper);
return Optional.ofNullable(mapper.apply(value));
}
}
chcemy uzyskać spójne zachowanie między 2 pierwszych fragmentów. Każdy powód, dla którego map()
nie jest drugą implementacją?
Dobry połów. Każdy pomysł, dlaczego nie sprawdzanie funkcji null tylko wtedy, gdy funkcja jest rzeczywiście wywoływana? – matthieus
@matthieus Obawiam się, że nie mogę powiedzieć. Nie mogłem znaleźć żadnej wiadomości z listy dyskusyjnej OpenJDK na ten temat (jest to najprawdopodobniej oparte na opiniach). – Tunaki
Właściwie to jest naprawdę dziwne, że działa ['orElseGet'] (https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#orElseGet-java.util.function.Supplier-) w inny sposób: rzuca NPE tylko wtedy, gdy dostawca ma wartość null * i * nie ma wartości. Paul Sandoz [uzgodniony] (http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-September/035426.html) że omawiana specyfikacja 'orElseGet' została wykonana w ten sposób przez pomyłkę. –