java.util.Objects.isNull vs object == null

88

Jak wiesz, java.util.Objectsjest

Ta klasa składa się ze statycznych metod narzędziowych do wykonywania operacji na obiektach.

Jedną z takich metod jest Objects.isNull().

Rozumiem, Objects.isNull()że wyeliminowałoby to możliwość przypadkowego przypisania wartości zerowej do obiektu poprzez pominięcie drugiej =.

Jednak uwaga API stwierdza:

Ta metoda istnieje do użycia jako predykat, filtr (Objects :: isNull)

Czy istnieje jakikolwiek powód / okoliczność, dla których warto korzystać z object == nullponad Objects.isNull()w if ?

Czy powinno Objects.isNull()się ograniczyć wyłącznie do orzeczeń?

Lucas T.
źródło
3
Jeśli martwisz się tylko przypadkowym przydziałem, możesz po prostu używać if(null == variable)konsekwentnie…
Holger
1
@Holder, o jakie przypadkowe przypisanie masz się martwić? To jest Java. Pojawi się błąd typu.
Louis Wasserman
1
@LouisWasserman Nie, jeśli variablejest Boolean.
Alexis C.
2
@AlexisC, to byłby problem w bardzo małej liczbie przypadków: twoja zmienna musi być bardzo specyficznego typu i musisz wprowadzić bardzo konkretną literówkę i nie możesz używać żadnego IDE ani analizy kompilatora to wskazywałoby na to (jak prawie wszystkie IDE). Czuję się dobrze, nie martwiąc się o tę sprawę.
Louis Wasserman
1
W pracy widziałem wiele wystąpień obiektu null == . Kiedy zapytałem, powiedziano mi, że ma to zapobiec przypadkowym zerowym przypisaniom. Na podstawie udzielonych tu komentarzy i odpowiedzi skłonny byłbym wierzyć, że to kwestia gustu.
Lucas T

Odpowiedzi:

79

należy używać object == null nad Objects.isNull () w instrukcji if?

Jeśli spojrzeć na kod źródłowy w IsNullmetodzie

 /* Returns true if the provided reference is null otherwise returns false.*/

 public static boolean isNull(Object obj) {
     return obj == null;
 }

To jest to samo. Nie ma różnicy. Więc możesz go bezpiecznie używać.

Suresh Atta
źródło
14
Tak, może być używany, ale może kolidować z analizą przepływu lokalnego wykonywaną przez narzędzie. To znaczy, ze zwykłym "==", każda analiza przepływu może zobaczyć, że dereferencja nie jest dobra w gałęzi to, ale jest bezpieczna w gałęzi else. Otrzymasz odpowiednie błędy / ostrzeżenia lub nic. W przypadku pośredniego wywołania metody isNull () ta wiedza może zostać utracona dla narzędzia.
Stephan Herrmann
3
Występuje niewielka różnica w wydajności. Sprawdzanie języka Java pod kątem odwołania do obiektu o wartości zerowej a wywoływanie metody statycznej będzie miało różnicę. I czyta się nieco mniej wyraźnie niż zwykłe użycie ==, do którego wszyscy jesteśmy przyzwyczajeni.
Kevin M
3
Jest bardziej semantyczne == nullw programie if, ale isNull świetnie nadaje się do użycia w wyrażeniach lambda.
Leonardo Ramos Duarte
1
jest to z pewnością uzasadnione, ale nie ma żadnych korzyści w stosunku do operatorów. Więc jeśli pracujesz w zespole, używaj rzeczy zgodnie z ich przeznaczeniem.
Alex Panchenko,
74

Objects.isNull jest przeznaczony do użycia z filtrowaniem lambda Java 8.

O wiele łatwiej i jaśniej jest pisać:

.stream().filter(Objects::isNull) 

niż pisać:

.stream().filter(x -> x == null).  

ifJednak w ramach oświadczenia oba będą działać. Użycie języka == nulljest prawdopodobnie łatwiejsze do odczytania, ale ostatecznie sprowadzi się do preferencji stylu.

Craig Taylor
źródło
12

Spójrz na źródło:

public static boolean isNull(Object obj) {
    return obj == null;
}

Aby sprawdzić nullwartości, możesz użyć:

  • Objects.isNull(myObject)
  • null == myObject // avoids assigning by typo
  • myObject == null // risk of typo

Fakt, że Objects.isNulljest przeznaczony dla Predicates, nie przeszkadza w używaniu go jak powyżej.

Mena
źródło
1
Co masz na myśli mówiąc o ryzyku literówki?
Ashish Lohia,
2
@AshishLohia, używając =zamiast ==(nie można kompilować, chyba że jest to Booleanopakowanie dopuszczające wartość null , bądź sprawiedliwy)
Mena
5
Ryzyko literówki występuje w C ++, a nie w Javie, jeśli (myObject = null) spowoduje błąd kompilacji. Zawsze powinieneś używać myObject == null zamiast null == myObject.
Tomas Marik
1
@TomasMarik Jak wspomniano w moim komentarzu, ryzyko literówki jest ograniczone do Booleanopakowań dopuszczających wartość null w Javie. Jest to rzeczywiście dość rzadkie (i daje kompilatorowi ostrzeżenia, gdy przypisanie do nulljest sprawdzane tak, jakby było warunkiem), ale nie jest niemożliwe.
Mena
7

Czy byłby jakiś powód / okoliczność, dla której powinienem używać object == null nad Objects.isNull () w instrukcji if ?

Tak, jednym z powodów jest prostota kodu. Wewnątrz, jeśli stwierdzenie object == null jest jasne i dobrze znane. Nie może to prowadzić do niewłaściwego zachowania, jeśli na przykład pojawi się literówka.

Rozumiem, że Objects.isNull () wyeliminowałoby możliwość przypadkowego przypisania wartości null do obiektu poprzez pominięcie second =.

Jeśli zostanie pominiętyif (object = null) {} z, nie będzie się kompilował lub wygeneruje ostrzeżenie w przypadku obiektu! W rzeczywistości nie ma powodu, aby używać instrukcji over within if . Oto dwa warianty obok siebie: =BooleanObjects.isNull(object)object == null

if (object == null) {
}

if (Objects.isNull(object)) {
}

Czy Objects.isNull () powinno być ograniczone wyłącznie do predykatów?

Można powiedzieć, że tak, ogranicza się to wyłącznie do orzeczeń, chociaż nie ma technicznych przeszkód w używaniu Objects.isNull()wszędzie.

Z public static boolean isNull(Object obj)javadoc metody:

@apiNote Ta metoda istnieje do wykorzystania jako java.util.function.Predicate, filter (Objects :: isNull)

Więc jeśli używasz metody jak nie orzecznika jesteś rzeczywiście przy bardziej złożonych i uciążliwych ekspresji w porównaniu do prostych object == null.

Oto fragment, z którego można porównać korzyści Objects.isNull(object)

List<String> list = Arrays.asList("a", "b", null, "c", null);

// As ready-made predicate
long countNullsWithPredicate = list.stream().filter(Objects::isNull).count();

// Lambda
long countNullsWithLambda = list.stream().filter(object -> object == null).count();

// Reimplement the Objects::isNull predicate
long countNullsWithAnonymous = list.stream().filter(new Predicate<Object>() {
    @Override
    public boolean test(Object obj) {
        return obj == null;
    }
}).count();
Wasyl
źródło
1

Pod względem semantycznym nie ma różnicy, ale ze względu na czytelność wolę następujące rzeczy whatever == null:

import static java.util.Objects.isNull;

// Other stuff...

if(isNull(whatever)) { 

}
angry_snyder
źródło