Unikanie!= null statements

Używam object != null dużo, aby uniknąć NullPointerException.

Czy jest na to dobra alternatywa?

Na przykład:

if (someobject != null) {
    someobject.doCalc();
}

Pozwala to uniknąć NullPointerException, gdy nie wiadomo, czy obiekt jest null, czy nie.

Zauważ, że zaakceptowana odpowiedź może być nieaktualna, zobacz https://stackoverflow.com/a/2386013/12943 dla nowszego podejścia.

Author: Goran Martinic, 2008-11-07

30 answers

Dla mnie brzmi to jak dość powszechny problem, z którym młodsi i średniozaawansowani deweloperzy mają tendencję do stawienia czoła w pewnym momencie: albo nie wiedzą, albo nie ufają kontraktom, w których uczestniczą i defensywnie sprawdzają null. Dodatkowo, pisząc własny kod, zwykle polegają na zwracaniu Null, aby wskazać coś, co wymaga od wywołującego sprawdzenia null.

Inaczej mówiąc, istnieją dwa przypadki, w których sprawdzanie null up:

  1. Gdzie null jest ważną odpowiedzią w warunkach umowy; i

  2. Gdzie nie jest to prawidłowa odpowiedź.

(2) jest łatwe. Należy użyć instrukcji assert (assertions) lub zezwolić na niepowodzenie (na przykład NullPointerException). Assertions to wysoce nieużywana funkcja Javy, która została dodana w wersji 1.4. Składnia to:

assert <condition>

Lub

assert <condition> : <object>

Gdzie <condition> jest wyrażeniem boolowskim, a {[10] } jest obiektem, którego toString() wynik metody zostanie uwzględniony w błędzie.

An assert twierdzenie rzuca Error (AssertionError) jeśli warunek nie jest prawdziwy. Domyślnie Java ignoruje twierdzenia. Można włączyć twierdzenia przekazując opcję -ea do JVM. Można włączać i wyłączać asercje dla poszczególnych klas i pakietów. Oznacza to, że możesz walidować kod z twierdzeniami podczas tworzenia i testowania oraz wyłączać je w środowisku produkcyjnym, chociaż moje testy pokazały obok no wpływ na wydajność z twierdzeń.

Nie używanie twierdzeń w tym przypadku jest w porządku, ponieważ kod po prostu zawiedzie, co się stanie, jeśli użyjesz twierdzeń. Jedyną różnicą jest to, że z twierdzeniami może to nastąpić wcześniej, w bardziej znaczący sposób i ewentualnie z dodatkowymi informacjami, które mogą pomóc ci dowiedzieć się, dlaczego tak się stało, jeśli się tego nie spodziewałeś.

(1) jest trochę trudniejsze. Jeśli nie masz kontroli nad kodem, do którego dzwonisz, utknąłeś. If null to prawidłowa odpowiedź, musisz ją sprawdzić.

Jeśli jednak jest to kod, który kontrolujesz (i często tak się dzieje), to jest to inna historia. Unikaj używania null jako odpowiedzi. Przy metodach zwracających Kolekcje jest to proste: zwracają puste Kolekcje (lub tablice) zamiast null praktycznie cały czas.

Z nie-zbiorami może być trudniej. Rozważ to jako przykład: jeśli masz te interfejsy:

public interface Action {
  void doSomething();
}

public interface Parser {
  Action findAction(String userInput);
}

Gdzie Parser pobiera surowe dane użytkownika i znajdzie coś do zrobienia, być może jeśli implementujesz interfejs wiersza poleceń do czegoś. Teraz możesz uczynić kontrakt, który zwróci null, jeśli nie ma odpowiednich działań. To prowadzi do sprawdzenia, o którym mówisz.

Alternatywnym rozwiązaniem jest, aby nigdy nie zwracać null i zamiast tego użyć wzorca obiektu Null :

public class MyParser implements Parser {
  private static Action DO_NOTHING = new Action() {
    public void doSomething() { /* do nothing */ }
  };

  public Action findAction(String userInput) {
    // ...
    if ( /* we can't find any actions */ ) {
      return DO_NOTHING;
    }
  }
}

Porównaj:

Parser parser = ParserFactory.getParser();
if (parser == null) {
  // now what?
  // this would be an example of where null isn't (or shouldn't be) a valid response
}
Action action = parser.findAction(someInput);
if (action == null) {
  // do nothing
} else {
  action.doSomething();
}

Do

ParserFactory.getParser().findAction(someInput).doSomething();

Który jest znacznie lepszym projektem, ponieważ prowadzi do bardziej zwięzłego kod.

To powiedziawszy, być może jest całkowicie właściwe, aby metoda findAction() wyrzuciła wyjątek ze znaczącym Komunikatem o błędzie - szczególnie w tym przypadku, gdy polegasz na danych wejściowych użytkownika. Byłoby znacznie lepiej, gdyby metoda findAction wyrzuciła wyjątek, niż gdyby wywołanie metody wysadziło się z prostym odstępem NullPointerException bez wyjaśnienia.

try {
    ParserFactory.getParser().findAction(someInput).doSomething();
} catch(ActionNotFoundException anfe) {
    userConsole.err(anfe.getMessage());
}

Lub jeśli uważasz, że mechanizm try/catch jest zbyt brzydki, zamiast nic nie robić, domyślna akcja powinny przekazywać informacje zwrotne użytkownikowi.

public Action findAction(final String userInput) {
    /* Code to return requested Action if found */
    return new Action() {
        public void doSomething() {
            userConsole.err("Action not found: " + userInput);
        }
    }
}
 2426
Author: cletus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-26 22:32:33

Jeśli używasz (lub planujesz użyć) Java IDE, takiego jak JetBrains IntelliJ IDEA, Eclipse lub Netbeans lub narzędzia takiego jak findbugs, możesz użyć adnotacji, aby rozwiązać ten problem.

W zasadzie masz @Nullable i @NotNull.

Możesz użyć w metodzie i parametrach, jak to:

@NotNull public static String helloWorld() {
    return "Hello World";
}

Lub

@Nullable public static String helloWorld() {
    return "Hello World";
}

Drugi przykład nie będzie kompilowany (w IntelliJ IDEA).

Gdy użyjesz pierwszej funkcji {[9] } w innym kawałku kod:

public static void main(String[] args)
{
    String result = helloWorld();
    if(result != null) {
        System.out.println(result);
    }
}

Teraz kompilator IntelliJ IDEA powie Ci, że sprawdzanie jest bezużyteczne, ponieważ helloWorld() funkcja nigdy nie zwróci null.

Użycie parametru

void someMethod(@NotNull someParameter) { }

Jeśli napiszesz coś w stylu:

someMethod(null);

To się nie skompiluje.

Ostatni przykład użycia @Nullable

@Nullable iWantToDestroyEverything() { return null; }

Robienie tego

iWantToDestroyEverything().something();
I możesz być pewien, że do tego nie dojdzie. :)

Jest to dobry sposób, aby kompilator sprawdzał coś więcej niż zwykle i aby wyegzekwować mocniejsze Kontrakty. Niestety, nie jest on obsługiwany przez wszystkie Kompilatory.

W IntelliJ IDEA 10.5 i on dodali wsparcie dla innych @Nullable @NotNull wdrożenia.

Zobacz wpis na blogubardziej elastyczne i konfigurowalne adnotacje @Nullable/@NotNull.

 530
Author: Luca Molteni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-17 17:12:48

Jeśli wartości null nie są dozwolone

Jeśli twoja metoda nazywa się zewnętrznie, zacznij od czegoś takiego:

public void method(Object object) {
  if (object == null) {
    throw new IllegalArgumentException("...");
  }

Następnie, w pozostałej części tej metody, będziesz wiedział, że object nie jest null.

Jeśli jest to metoda wewnętrzna (Nie część API), po prostu dokument, że nie może być null, i to wszystko.

Przykład:

public String getFirst3Chars(String text) {
  return text.subString(0, 3);
}

Jednakże, jeśli twoja metoda po prostu przekazuje wartość dalej, a następna metoda przekazuje ją dalej itd. to może być problematyczne. W takim razie możesz chcieć aby sprawdzić argument jak powyżej.

Jeśli dozwolone jest null

To naprawdę zależy. Jeśli okaże się, że często robię coś takiego:
if (object == null) {
  // something
} else {
  // something else
}
Więc rozgałęziam się i robię dwie zupełnie różne rzeczy. Nie ma brzydkiego fragmentu kodu, ponieważ naprawdę muszę zrobić dwie różne rzeczy w zależności od danych. Na przykład, Czy powinienem pracować nad danymi wejściowymi, czy powinienem obliczyć dobrą wartość domyślną?
Rzadko zdarza mi się używać idiomu "if (object != null && ...".

It may be easier to podaj przykłady, jeśli pokażesz przykłady, gdzie zwykle używasz idiomu.

 288
Author: myplacedk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-19 09:02:46

Wow, prawie nie lubię dodawać kolejnej odpowiedzi, gdy mamy 57 różnych sposobów polecania NullObject pattern, ale myślę, że niektórzy zainteresowani tym pytaniem mogą chcieć wiedzieć, że istnieje propozycja dodania "null-safe handling"-usprawnionej składni dla logiki if-not-equal-null.

Przykład podany przez Alexa Millera wygląda tak:

public String getPostcode(Person person) {  
  return person?.getAddress()?.getPostcode();  
}  

?. oznacza tylko odwołanie do lewego identyfikatora, jeśli nie jest null, w przeciwnym razie Oceń resztę wyrażenia jako null. Niektórzy ludzie, jak członek Java Posse Dick Wall i wyborcy W Devoxx naprawdę kochają tę propozycję, ale jest też opozycja, ponieważ będzie ona zachęcać do większego wykorzystania null jako wartości wartowniczej.


Update: oficjalna propozycja dla bezpiecznego operatora w Javie 7 została złożona w ramach Project Coin. składnia jest trochę inna niż w powyższym przykładzie, ale jest taka sama pomysł.


Update: propozycja bezpiecznego operatora null nie trafiła do projektu Coin. Nie zobaczysz więc tej składni w Javie 7.

 218
Author: erickson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-20 23:12:27

Jeśli wartości niezdefiniowane nie są dozwolone:

Możesz skonfigurować IDE tak, aby ostrzegało Cię o potencjalnym dereferencji null. Np. w Eclipse, patrz Preferences > Java > Compiler > Errors/Warnings/null analysis.

Jeśli dozwolone są wartości niezdefiniowane:

Jeśli chcesz zdefiniować nowe API, w którym niezdefiniowane wartości mają sens , użyj wzorca opcji (Może być znany z języków funkcyjnych). Ma następujące zalety:

  • It jest wyraźnie określone w API, czy dane wejściowe lub wyjściowe istnieją, czy nie.
  • kompilator zmusza cię do obsługi sprawy "undefined".
  • opcja jest monad , więc nie ma potrzeby sprawdzania verbose null, wystarczy użyć map / foreach / getOrElse lub podobnego kombinatora, aby bezpiecznie używać wartości (przykład).

Java 8 ma wbudowany Optional klasy (zalecane); dla wcześniejszych wersji istnieją alternatywy biblioteczne, na przykład guawa's Optional lub Funkcjonaljava's Option. Ale jak wiele wzorców funkcjonalnych, użycie opcji w Javie (nawet 8) skutkuje dość dużą płytą, którą można zmniejszyć używając mniej wyrazistego języka JVM, np. Scala lub Xtend.

Jeśli masz do czynienia z API, które może zwracać nulls , nie możesz wiele zrobić w Javie. Xtend i Groovy mają operator Elvisa ?: oraz null-Bezpieczny operator dereferencyjny ?., ale zauważ, że zwraca null w przypadku odniesienia null, więc po prostu "odkłada" właściwe postępowanie z null.

 180
Author: thSoft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-24 10:38:40

Tylko w tej sytuacji -

Nie sprawdzanie, czy zmienna ma wartość null przed wywołaniem metody equals (przykład porównywania łańcuchów poniżej):

if ( foo.equals("bar") ) {
 // ...
}

Spowoduje NullPointerException, Jeśli foo nie istnieje.

Możesz tego uniknąć, jeśli porównasz swoje String w ten sposób:

if ( "bar".equals(foo) ) {
 // ...
}
 165
Author: echox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-25 15:33:50

W Javie 8 pojawia się nowa klasa java.util.Optional, która prawdopodobnie rozwiązuje część problemu. Można przynajmniej powiedzieć, że poprawia to czytelność kodu, a w przypadku publicznych API sprawia, że umowa API jest jaśniejsza dla dewelopera klienta.

Tak działają:

Opcjonalny obiekt dla danego typu (Fruit) jest tworzony jako typ zwracany metody. Może być pusty lub zawierać obiekt Fruit:

public static Optional<Fruit> find(String name, List<Fruit> fruits) {
   for (Fruit fruit : fruits) {
      if (fruit.getName().equals(name)) {
         return Optional.of(fruit);
      }
   }
   return Optional.empty();
}

Teraz spójrz na ten kod, gdzie przeszukujemy listę Fruit (fruits) dla danej instancji owocu:

Optional<Fruit> found = find("lemon", fruits);
if (found.isPresent()) {
   Fruit fruit = found.get();
   String name = fruit.getName();
}

Możesz użyć operatora map(), aby wykonać obliczenia na--lub wyodrębnić wartość z -- opcjonalnego obiektu. orElse() pozwala zapewnić zastępstwo dla brakujących wartości.

String nameOrNull = find("lemon", fruits)
    .map(f -> f.getName())
    .orElse("empty-name");

Oczywiście, sprawdzenie wartości null / empty jest nadal konieczne, ale przynajmniej programista jest świadomy, że wartość może być pusta i ryzyko zapomnienia o sprawdzeniu jest ograniczone.

W API zbudowanym od podstaw przy użyciu Optional gdy zwracana wartość może być pusty, a zwracanie zwykłego obiektu tylko wtedy, gdy nie może być null (konwencja), kod klienta może zrezygnować z null sprawdzania wartości zwracanych przez prosty obiekt...

Oczywiście Optional może być również używany jako argument metody, być może lepszy sposób na wskazanie opcjonalnych argumentów niż 5 lub 10 metod przeciążających w niektórych przypadkach.

Optional oferuje inne wygodne metody, takie jak orElse, które pozwalają na użycie wartości domyślnej, i ifPresent, który działa z lambda wyrażenia .

Zapraszam do przeczytania tego artykułu (moje główne źródło do napisania tej odpowiedzi), w którym NullPointerException (i ogólnie wskaźnik null) problematyczne, jak również (częściowe) rozwiązanie wniesione przez Optional są dobrze wyjaśnione: Java opcjonalne Obiekty.

 140
Author: Pierre Henry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-29 07:39:04

W zależności od tego, jakie obiekty sprawdzasz, możesz używać niektórych klas w Apache commons, takich jak: apache commons lang i Apache commons collections

Przykład:

String foo;
...
if( StringUtils.isBlank( foo ) ) {
   ///do something
}

Lub (w zależności od tego, co trzeba sprawdzić):

String foo;
...
if( StringUtils.isEmpty( foo ) ) {
   ///do something
}

Klasa StringUtils jest tylko jedną z wielu; jest sporo dobrych klas na commons, które nie potrafią bezpiecznie manipulować.

Oto przykład jak możesz użyć null vallidation w Javie po dołączeniu biblioteki apache (commons-lang-2.4.jar)

public DOCUMENT read(String xml, ValidationEventHandler validationEventHandler) {
    Validate.notNull(validationEventHandler,"ValidationHandler not Injected");
    return read(new StringReader(xml), true, validationEventHandler);
}

A jeśli używasz sprężyny, Spring również ma taką samą funkcjonalność w swoim pakiecie, patrz biblioteka (spring-2.4.6.jar)

Przykład użycia tej statycznej classf ze springa (org.springframework.util.Assert)

Assert.notNull(validationEventHandler,"ValidationHandler not Injected");
 115
Author: javamonkey79,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-23 12:14:13
  • Jeśli uważasz, że obiekt nie powinien być null (lub jest to błąd), użyj assert.
  • Jeśli twoja metoda nie akceptuje param null, Powiedz to w javadoc i użyj assert.

Musisz sprawdzić obiekt != null tylko jeśli chcesz obsłużyć przypadek, w którym obiekt może być null...

Istnieje propozycja dodania nowych adnotacji w Java7, aby pomóc w paramach null / notnull: http://tech.puredanger.com/java7/#jsr308

 89
Author: pgras,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-14 14:44:48

Jestem fanem kodu "Fail fast". Zadaj sobie pytanie - czy robisz coś pożytecznego w przypadku, gdy parametr jest null? Jeśli nie masz jasnej odpowiedzi na to, co twój kod powinien zrobić w takim przypadku... Tj. w pierwszej kolejności nie powinno być null, a następnie ignorować i zezwalać na odrzucenie NullPointerException. Kod wywołujący będzie miał taki sam sens jak NPE, ale programista będzie łatwiej debugować i zrozumieć, co poszło nie tak, jeśli NPE jest wyrzucany zamiast kodu, który próbuje wykonać inną nieoczekiwaną logikę awaryjną - co ostatecznie skutkuje awarią aplikacji.

 82
Author: Alex Worden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-23 19:09:09

Google collections framework oferuje dobry i elegancki sposób na osiągnięcie zerowej kontroli.

W klasie biblioteki jest taka metoda:

static <T> T checkNotNull(T e) {
   if (e == null) {
      throw new NullPointerException();
   }
   return e;
}

I użycie jest (z import static):

...
void foo(int a, Person p) {
   if (checkNotNull(p).getAge() > a) {
      ...
   }
   else {
      ...
   }
}
...

Lub w twoim przykładzie:

checkNotNull(someobject).doCalc();
 71
Author: user2427,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-19 16:05:47

Czasami masz metody, które działają na jego parametrach, które definiują operację symetryczną:

a.f(b); <-> b.f(a);

Jeśli wiesz, że b nigdy nie może być zerowe, możesz je po prostu zamienić. Jest to najbardziej przydatne dla równych: Zamiast foo.equals("bar"); lepiej zrobić "bar".equals(foo);.

 70
Author: Johannes Schaub - litb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-15 19:02:51

Zamiast wzorca obiektu Null -- który ma swoje zastosowania -- można rozważyć sytuacje, w których obiekt null jest błędem.

Gdy wyjątek jest wyrzucany, sprawdź ślad stosu i pracuj nad błędem.

 68
Author: Jim Nelson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-07 08:50:24

Java 7 ma nową klasę narzędzi java.util.Objects, w której znajduje się metoda requireNonNull(). Wystarczy rzucić NullPointerException, jeśli jego argument jest null, ale trochę wyczyści kod. Przykład:

Objects.requireNonNull(someObject);
someObject.doCalc();

Metoda jest najbardziej przydatna do sprawdzania tuż przed przypisaniem do konstruktora, gdzie każde jej użycie może zapisać trzy linijki kodu:

Parent(Child child) {
   if (child == null) {
      throw new NullPointerException("child");
   }
   this.child = child;
}

Staje się

Parent(Child child) {
   this.child = Objects.requireNonNull(child, "child");
}
 66
Author: Raedwald,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:33

Null nie jest 'problemem'. Jest integralną częścią kompletnego zestawu narzędzi do modelowania. Oprogramowanie ma na celu modelowanie złożoności świata i null ponosi jego ciężar. Null oznacza "brak danych" lub "Nieznany" w Javie i tym podobnych. Dlatego właściwe jest użycie NULL do tych celów. Nie preferuję wzorca 'null object'; myślę, że podnosi on ' Kto będzie strzegł strażnicy ' problem.
Jeśli zapytasz mnie, jak ma na imię moja dziewczyna, powiem ci, że nie mam dziewczyny. W języku Java zwrócę null. Alternatywą byłoby rzucenie znaczącego wyjątku, aby wskazać jakiś problem ,którego nie można (lub nie chcesz) rozwiązać, i delegować go gdzieś wyżej w stosie, aby ponowić próbę lub zgłosić błąd dostępu do danych użytkownikowi.

  1. Na "nieznane pytanie" podaj "nieznaną odpowiedź". (Be null-safe tam, gdzie jest to poprawne z biznesowego punktu widzenia) sprawdzanie argumentów dla null raz wewnątrz metody przed użyciem zwalnia wielu rozmówców z ich sprawdzania przed połączeniem.

    public Photo getPhotoOfThePerson(Person person) {
        if (person == null)
            return null;
        // Grabbing some resources or intensive calculation
        // using person object anyhow.
    }
    

    Poprzednie prowadzi do normalnego przepływu logiki, aby nie uzyskać zdjęcia nieistniejącej dziewczyny z mojej biblioteki zdjęć.

    getPhotoOfThePerson(me.getGirlfriend())
    
    [23]} i pasuje do nowego nadchodzącego API Java (looking forward)
    getPhotoByName(me.getGirlfriend()?.getName())
    

    Chociaż jest to raczej' normalny przepływ biznesowy', aby nie znaleźć zdjęcia zapisanego w DB dla jakiejś osoby, używałem par jak poniżej dla niektórych innych przypadków

    public static MyEnum parseMyEnum(String value); // throws IllegalArgumentException
    public static MyEnum parseMyEnumOrNull(String value);
    

    I nie brzydź się pisać <alt> + <shift> + <j> (Wygeneruj javadoc w Eclipse) i napisz trzy dodatkowe słowa dla Twojego publicznego API. To będzie więcej niż wystarczające dla wszystkich, ale tych, którzy nie czytają dokumentacji.

    /**
     * @return photo or null
     */
    

    Lub

    /**
     * @return photo, never null
     */
    
  2. Jest to raczej teoretyczny przypadek i w większości przypadków powinieneś preferować java null safe API (na wypadek, gdyby zostało wydane za kolejne 10 lat), ale NullPointerException jest podklasą Exception. jest to więc forma Throwable, która wskazuje warunki, które rozsądny wniosek może chcieć aby złapać ( javadoc )! Aby wykorzystać pierwszą największą zaletę wyjątków i oddzielić kod obsługi błędów od 'zwykłego' kodu (według twórców Javy ), należy, jak dla mnie, złapać NullPointerException.

    public Photo getGirlfriendPhoto() {
        try {
            return appContext.getPhotoDataSource().getPhotoByName(me.getGirlfriend().getName());
        } catch (NullPointerException e) {
            return null;
        }
    }
    

    Mogą pojawić się pytania:

    Q. co jeśli getPhotoDataSource() zwróci null?
    A. to zależy od logiki biznesowej. Jeśli nie znajdę albumu ze zdjęciami, nie pokażę Ci żadnych zdjęć. Co się stanie, jeśli appContext nie zostanie zainicjowany? Logika biznesowa tej metody to znosi. Jeśli ta sama logika powinna być bardziej rygorystyczna niż rzucanie wyjątku. jest to część logiki biznesowej i należy użyć jawnego sprawdzania null (przypadek 3). nowe API Java Null-safe lepiej pasuje tutaj, aby określić selektywnie, co implikuje, a co nie implikuje, aby inicjalizacja była szybka w przypadku błędów programistycznych.

    Q. można wykonać nadmiarowy kod i pobrać niepotrzebne zasoby.
    O. może to nastąpić, jeśli getPhotoByName() spróbuje otworzyć połączenie z bazą danych, Utwórz PreparedStatement i użyj nazwy osoby jako parametru SQL. Podejście do nieznanego pytania daje nieznaną odpowiedź (przypadek 1) działa tutaj. Przed pobraniem zasobów metoda powinna sprawdzić parametry i w razie potrzeby zwrócić "nieznany" wynik.

    Q. takie podejście ma karę wydajności z powodu otwarcia zamknięcia próby.
    A. oprogramowanie powinno być najpierw łatwe do zrozumienia i modyfikacji. Dopiero po tym można było myśleć o wydajności i tylko wtedy, gdy było to konieczne! i gdzie potrzebne! (źródło ) i wiele innych).

    PS. Podejście to będzie tak samo rozsądne w użyciu, jak zasada oddzielnego kodu obsługi błędów od zasady" zwykłego " kodu jest rozsądna do użycia w jakimś miejscu. Rozważmy następny przykład:

    public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {
        try {
            Result1 result1 = performSomeCalculation(predicate);
            Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());
            Result3 result3 = performThirdCalculation(result2.getSomeProperty());
            Result4 result4 = performLastCalculation(result3.getSomeProperty());
            return result4.getSomeProperty();
        } catch (NullPointerException e) {
            return null;
        }
    }
    
    public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {
        SomeValue result = null;
        if (predicate != null) {
            Result1 result1 = performSomeCalculation(predicate);
            if (result1 != null && result1.getSomeProperty() != null) {
                Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());
                if (result2 != null && result2.getSomeProperty() != null) {
                    Result3 result3 = performThirdCalculation(result2.getSomeProperty());
                    if (result3 != null && result3.getSomeProperty() != null) {
                        Result4 result4 = performLastCalculation(result3.getSomeProperty());
                        if (result4 != null) {
                            result = result4.getSomeProperty();
                        }
                    }
                }
            }
        }
        return result;
    }
    

    PPS. Dla tych, którzy szybko obniżają głos (a nie tak szybko czytają dokumentację) chciałbym powiedzieć, że nigdy w życiu nie złapałem wyjątku null-pointer (NPE). Ale ta możliwość została celowo zaprojektowana przez Javę twórcy, ponieważ NPE jest podklasą Exception. Mamy precedens w historii Javy, gdy ThreadDeath jest Error Nie dlatego, że jest to błąd aplikacji, ale tylko dlatego, że nie został on zamierzony do przechwycenia! Ile NPE pasuje do Error niż ThreadDeath! Ale tak nie jest.

  3. Sprawdź "brak danych" tylko wtedy, gdy zakłada to logika biznesowa.

    public void updatePersonPhoneNumber(Long personId, String phoneNumber) {
        if (personId == null)
            return;
        DataSource dataSource = appContext.getStuffDataSource();
        Person person = dataSource.getPersonById(personId);
        if (person != null) {
            person.setPhoneNumber(phoneNumber);
            dataSource.updatePerson(person);
        } else {
            Person = new Person(personId);
            person.setPhoneNumber(phoneNumber);
            dataSource.insertPerson(person);
        }
    }
    

    I

    public void updatePersonPhoneNumber(Long personId, String phoneNumber) {
        if (personId == null)
            return;
        DataSource dataSource = appContext.getStuffDataSource();
        Person person = dataSource.getPersonById(personId);
        if (person == null)
            throw new SomeReasonableUserException("What are you thinking about ???");
        person.setPhoneNumber(phoneNumber);
        dataSource.updatePerson(person);
    }
    

    Jeśli appContext lub dataSource nie zostaną zainicjowane, nieobsługiwany runtime NullPointerException będzie wyłącz bieżący wątek i będzie przetwarzany przez wątek .defaultUncaughtExceptionHandler (aby zdefiniować i użyć ulubionego rejestratora lub innego mechanizmu powiadomień). Jeśli nie jest ustawione, ThreadGroup#uncaughtException wyświetli stacktrace do systemu err. Należy monitorować dziennik błędów aplikacji i otworzyć problem Jira dla każdego nieobsługiwanego wyjątku, który w rzeczywistości jest błędem aplikacji. Programista powinien naprawić błąd gdzieś w rzeczy inicjalizacji.

 64
Author: Mykhaylo Adamovych,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-23 22:03:07

Ostatecznie jedynym sposobem na całkowite rozwiązanie tego problemu jest użycie innego języka programowania:

  • w Objective-C, możesz wykonać odpowiednik wywołania metody na nil i absolutnie nic się nie stanie. To sprawia, że większość kontroli zerowych jest niepotrzebna, ale może to znacznie utrudnić diagnozowanie błędów.
  • W Nice, języku wywodzącym się z Javy, istnieją dwie wersje wszystkich typów: wersja potencjalnie-null i wersja nie-null. Możesz wywoływać tylko metody na typy not-null. Typy potencjalnie-null mogą być przekonwertowane na typy not-null poprzez jawne sprawdzanie pod kątem null. Dzięki temu znacznie łatwiej jest wiedzieć, gdzie kontrole null są konieczne, a gdzie nie.
 47
Author: Michael Borgwardt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-19 16:09:15

Powszechny "problem" w Javie.

Po pierwsze, moje przemyślenia na ten temat:

Uważam, że źle jest "zjeść" coś, gdy null zostało przekazane, gdzie NULL nie jest poprawną wartością. Jeśli nie opuszczasz metody z jakimś błędem, oznacza to, że nic nie poszło źle w Twojej metodzie, co nie jest prawdą. Wtedy prawdopodobnie zwracasz null w tym przypadku, a w metodzie otrzymującej ponownie sprawdzasz null i nigdy się to nie kończy, a kończy się na "if != null", itd..

Więc, IMHO, null musi to być błąd krytyczny, który uniemożliwia dalsze wykonanie (tzn. gdzie null nie jest poprawną wartością).

Sposób, w jaki rozwiązuję ten problem jest taki:

Po pierwsze, stosuję się do tej konwencji:

  1. Wszystkie publiczne metody / API zawsze sprawdzają jego argumenty pod kątem null
  2. Wszystkie prywatne metody nie sprawdzają null, ponieważ są metodami kontrolowanymi (po prostu pozwól umrzeć z wyjątkiem nullpointer na wypadek, gdyby nie było obsługiwane powyżej)
  3. jedyne inne metody, które nie sprawdzają null to metody użytkowe. Są publiczne, ale jeśli zadzwonisz do nich z jakiegoś powodu, wiesz, jakie parametry przekazujesz. To jest jak próba zagotowania wody w czajniku bez dostarczania wody...

I na koniec, w kodzie, pierwsza linijka metody publicznej wygląda tak:

ValidationUtils.getNullValidator().addParam(plans, "plans").addParam(persons, "persons").validate();

Zauważ, że addParam () zwraca self, dzięki czemu możesz dodać więcej parametrów do sprawdzenia.

Metoda validate() rzuci checked ValidationException Jeśli którykolwiek z parametrów jest null (zaznaczone lub niezaznaczone jest więcej problem z designem/smakiem, ale mój ValidationException jest sprawdzony).

void validate() throws ValidationException;

Wiadomość będzie zawierać następujący tekst, jeśli ,na przykład, "plany"jest null:

"nielegalna wartość argumentu null jest spotykana dla parametru [plany]"

Jak widać, druga wartość w metodzie addParam () (string) jest potrzebna do wiadomości użytkownika, ponieważ nie można łatwo wykryć przekazanej nazwy zmiennej, nawet przy odbiciu (Nie temat tego postu i tak...).

I tak, wiemy, że poza tą linią nie będziemy już napotykać wartości null, więc po prostu bezpiecznie wywołujemy metody na tych obiektach.

W ten sposób kod jest czysty, łatwy do utrzymania i czytelny.

 34
Author: Oleg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-19 19:00:35

Zadawanie tego pytania wskazuje, że możesz być zainteresowany strategiami obsługi błędów. Architekt Twojego zespołu powinien zdecydować, jak pracować z błędami. Istnieje kilka sposobów, aby to zrobić:

  1. Zezwalaj wyjątkom na tętnienie - łap je w 'pętli głównej' lub w innej rutynie zarządzającej.

    • sprawdź warunki błędów i odpowiednio je obsłuż

Na pewno też przyjrzyjcie się programowaniu Aspect Oriented - mają schludne sposoby wstawiania if( o == null ) handleNull() do kodu bajtowego.

 32
Author: xtofl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-07 09:27:17

Oprócz użycia assert możesz użyć następujących:

if (someobject == null) {
    // Handle null here then move on.
}

To jest nieco lepsze niż:

if (someobject != null) {
    .....
    .....



    .....
}
 32
Author: fastcodejava,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-19 17:14:39

Tylko nigdy nie używaj null. Nie pozwól na to.

W moich klasach, większość pól i zmiennych lokalnych ma inne niż null wartości domyślne, a ja dodaję deklaracje umowy (zawsze włączone twierdzenia) wszędzie w kodzie, aby upewnić się, że jest to egzekwowane (ponieważ jest to bardziej zwięzłe i bardziej wyraziste niż pozwalanie na to jako NPE, a następnie rozwiązywanie numeru linii itp.).

Kiedy przyjęłam tę praktykę, zauważyłam, że problemy wydają się same naprawiać. Dużo byś złapał wcześniej w procesie rozwoju tylko przez przypadek i uświadomić sobie, że masz słaby punkt.. i co ważniejsze.. pomaga to w zamykaniu problemów różnych modułów, różne moduły mogą sobie "ufać" i nie zaśmiecać kodu konstrukcjami if = null else!

Jest to programowanie defensywne i skutkuje znacznie czystszym kodem na dłuższą metę. Zawsze oczyszczaj dane, np. tutaj, egzekwując sztywne standardy, a problemy znikną.

class C {
    private final MyType mustBeSet;
    public C(MyType mything) {
       mustBeSet=Contract.notNull(mything);
    }
   private String name = "<unknown>";
   public void setName(String s) {
      name = Contract.notNull(s);
   }
}


class Contract {
    public static <T> T notNull(T t) { if (t == null) { throw new ContractException("argument must be non-null"); return t; }
}

Kontrakty są jak mini-testy jednostkowe które są zawsze uruchomione, nawet w produkcji, a kiedy rzeczy zawodzą, wiesz dlaczego, zamiast przypadkowego NPE trzeba jakoś dowiedzieć.

 30
Author: iangreen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-19 19:42:38

Guava, bardzo przydatna biblioteka bazowa Google, ma ładne i przydatne API, aby uniknąć null. Uważam, że używanie i używanie Nullexplained jest bardzo pomocne.

Jak wyjaśniono w wiki:

Optional<T> jest sposobem zastąpienia nullable T reference z wartość non-null. Opcjonalny może zawierać odniesienie inne niż null T (w takim przypadku mówimy, że Referencja jest "obecna"), lub może zawierać nic (w takim przypadku mówimy, że Referencja jest "nieobecna"). Nigdy nie jest powiedział do "contain null."

Użycie:

Optional<Integer> possible = Optional.of(5);
possible.isPresent(); // returns true
possible.get(); // returns 5
 28
Author: Murat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-07 21:03:14

Jest to bardzo powszechny problem dla każdego programisty Javy. Tak więc w Javie 8 istnieje oficjalne wsparcie, aby rozwiązać te problemy bez zaśmieconego kodu.

Java 8 wprowadziła java.util.Optional<T>. Jest to kontener, który może lub nie może zawierać wartości inne niż null. Java 8 dała bezpieczniejszy sposób obsługi obiektu, którego wartość może być null w niektórych przypadkach. Jest inspirowany ideami Haskell i Scala.

W skrócie, Klasa opcjonalna zawiera metody do jawnie radzić sobie z przypadkami, w których wartość jest obecna lub nieobecna. Jednak zaletą w porównaniu z referencjami null jest to, że opcjonalna Klasa zmusza do myślenia o Przypadku, Gdy wartość nie jest obecna. W konsekwencji można zapobiec niezamierzonym wyjątkom wskaźnika null.

W powyższym przykładzie mamy fabrykę usług domowych, która zwraca uchwyt do wielu urządzeń dostępnych w domu. Ale te usługi mogą lub nie mogą być dostępne/ funkcjonalne; oznacza to, że może to spowodować NullPointerException. Zamiast dodawać warunek null if przed użyciem jakiejkolwiek usługi, zawinąć go do opcjonalnego .

OWIJANIE DO OPCJI

Rozważmy metodę, aby uzyskać odniesienie do usługi z fabryki. Zamiast zwracać odniesienie do usługi, owinąć go opcjonalnym. Pozwala to użytkownikowi API wiedzieć, że zwrócona usługa może lub nie może być dostępna / funkcjonalna, używać defensywnie

public Optional<Service> getRefrigertorControl() {
      Service s = new  RefrigeratorService();
       //...
      return Optional.ofNullable(s);
   }

Jak widzisz Optional.ofNullable() zapewnia łatwy sposób na uzyskanie / align = "left" / Istnieją inne sposoby uzyskania odniesienia opcjonalnego, albo Optional.empty() & Optional.of(). Jeden służy do zwracania pustego obiektu zamiast retuningu null, a drugi do zawijania, odpowiednio, obiektu nie-nullable.

WIĘC JAK DOKŁADNIE POMAGA UNIKNĄĆ SPRAWDZENIA NULL?

Po owinięciu obiektu odniesienia, opcjonalne dostarcza wiele użytecznych metod do wywoływania metod na owiniętym obiekcie odniesienia bez NPE.

Optional ref = homeServices.getRefrigertorControl();
ref.ifPresent(HomeServices::switchItOn);

Opcjonalnie.jeżeli Klient powołuje się na danego konsumenta z reference, jeśli jest to wartość inna niż null. Inaczej nic nie zrobi.

@FunctionalInterface
public interface Consumer<T>

Reprezentuje operację, która przyjmuje pojedynczy argument wejściowy i nie zwraca żadnego wyniku. W przeciwieństwie do większości innych funkcjonalnych interfejsów, oczekuje się, że konsument będzie działał poprzez skutki uboczne. Jest tak czysty i łatwy do zrozumienia. W powyższym przykładzie kodu, {[10] } jest wywoływany, jeśli opcjonalne odniesienie do trzymania jest INNE niż null.

Używamy operatora ternary bardzo często do sprawdzania warunku null i zwracania alternatywy wartość lub wartość domyślna. Opcjonalne zapewnia inny sposób obsługi tego samego warunku bez sprawdzania null. Opcjonalnie.orElse (defaultObj) zwraca defaultObj, jeśli opcja ma wartość null. Użyjmy tego w naszym przykładowym kodzie:

public static Optional<HomeServices> get() {
    service = Optional.of(service.orElse(new HomeServices()));
    return service;
}

Teraz HomeServices.get() robi to samo, ale w lepszy sposób. Sprawdza, czy usługa jest już zainicjowana przez not. Jeśli jest to wtedy zwróć to samo lub utwórz nową nową usługę. Opcjonalne.orElse (T) pomaga zwrócić domyślną wartość.

Na koniec, oto nasz NPE oraz null check-free code:

import java.util.Optional;
public class HomeServices {
    private static final int NOW = 0;
    private static Optional<HomeServices> service;

public static Optional<HomeServices> get() {
    service = Optional.of(service.orElse(new HomeServices()));
    return service;
}

public Optional<Service> getRefrigertorControl() {
    Service s = new  RefrigeratorService();
    //...
    return Optional.ofNullable(s);
}

public static void main(String[] args) {
    /* Get Home Services handle */
    Optional<HomeServices> homeServices = HomeServices.get();
    if(homeServices != null) {
        Optional<Service> refrigertorControl = homeServices.get().getRefrigertorControl();
        refrigertorControl.ifPresent(HomeServices::switchItOn);
    }
}

public static void switchItOn(Service s){
         //...
    }
}

Kompletny post jest NPE jak i Null check-free code ... naprawdę?.

 20
Author: Yogesh Devatraj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-19 20:39:30

Lubię artykuły z Nat Pryce. Oto linki:

W artykułach jest też link do repozytorium Git dla typu Java, które może mnie zainteresować, ale nie wydaje mi się, aby samo to zmniejszyło sprawdzam kod. Po przeprowadzeniu pewnych badań w Internecie, myślę != null kod wzdęcia można zmniejszyć głównie poprzez ostrożne design.

 20
Author: Mr Palo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-12 02:49:30

Próbowałem NullObjectPattern ale dla mnie nie zawsze jest to najlepszy sposób. Czasami zdarza się, że "brak działania" nie jest odpowiedni.

NullPointerException jest wyjątkiem Runtime , co oznacza, że jest to wina programistów i z wystarczającym doświadczeniem mówi dokładnie, gdzie jest błąd.

Teraz odpowiedź:

Staraj się, aby wszystkie atrybuty i ich akcesoria były jak najbardziej prywatne lub unikaj wystawiania ich na działanie klientów. Możesz mieć wartości argumentów w konstruktorze oczywiście, ale zmniejszając zakres nie pozwalasz klasie klienta przekazać nieprawidłowej wartości. Jeśli chcesz zmodyfikować wartości, zawsze możesz utworzyć nową object. Sprawdzasz wartości w konstruktorze tylko raz , a w pozostałych metodach możesz być prawie pewien, że wartości nie są null. Oczywiście doświadczenie jest lepszym sposobem na zrozumienie i zastosowanie tej sugestii.

Bajt!

 18
Author: OscarRyz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-30 22:06:24

Prawdopodobnie najlepszą alternatywą dla Javy 8 lub nowszej jest użycie Optional klasy.

Optional stringToUse = Optional.of("optional is there");
stringToUse.ifPresent(System.out::println);

Jest to szczególnie przydatne w przypadku długich łańcuchów możliwych wartości null. Przykład:

Optional<Integer> i = Optional.ofNullable(wsObject.getFoo())
    .map(f -> f.getBar())
    .map(b -> b.getBaz())
    .map(b -> b.getInt());

Przykład jak rzucić wyjątek na null:

Optional optionalCarNull = Optional.ofNullable(someNull);
optionalCarNull.orElseThrow(IllegalStateException::new);

Java 7 wprowadziła Objects.requireNonNull metoda, która może być przydatna, gdy coś powinno być sprawdzone pod kątem braku nullness. Przykład:

String lowerVal = Objects.requireNonNull(someVar, "input cannot be null or empty").toLowerCase();
 15
Author: Raghu K Nair,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-29 07:35:54

Mogę odpowiedzieć bardziej ogólnie!

My Zwykle napotykamy ten problem, gdy metody uzyskują parametry w sposób, którego się nie spodziewaliśmy(złe wywołanie metody jest winą programisty). Na przykład: spodziewasz się, że otrzymasz obiekt, zamiast tego otrzymasz null. Spodziewasz się, że otrzymasz łańcuch z co najmniej jednym znakiem, zamiast tego otrzymasz pusty łańcuch ...

Więc nie ma różnicy między:

if(object == null){
   //you called my method badly!

}

Lub

if(str.length() == 0){
   //you called my method badly again!
}

Oboje chcą się upewnić, że otrzymaliśmy ważne parametrów, zanim wykonamy jakiekolwiek inne funkcje.

Jak wspomniano w innych odpowiedziach, aby uniknąć powyższych problemów, możesz zastosować wzórwedług umowy . Zobacz http://en.wikipedia.org/wiki/Design_by_contract .

Aby zaimplementować ten wzorzec w Javie, możesz użyć podstawowych adnotacji java, takich jak javax.adnotacja.NotNull lub używać bardziej zaawansowanych bibliotek, takich jak walidator Hibernate.

Tylko próbka:

getCustomerAccounts(@NotEmpty String customerId,@Size(min = 1) String accountType)

Teraz możesz bezpiecznie rozwijaj podstawową funkcję metody bez konieczności sprawdzania parametrów wejściowych, chronią metody przed nieoczekiwanymi parametrami.

Możesz pójść o krok dalej i upewnić się, że tylko ważne POJO mogą być tworzone w Twojej aplikacji. (sample from hibernate validator site)

public class Car {

   @NotNull
   private String manufacturer;

   @NotNull
   @Size(min = 2, max = 14)
   private String licensePlate;

   @Min(2)
   private int seatCount;

   // ...
}
 14
Author: Alireza Fattahi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-24 14:48:05

Bardzo lekceważę odpowiedzi sugerujące używanie obiektów null w każdej sytuacji. Ten wzorzec może złamać kontrakt i pogrzebać problemy coraz głębiej, zamiast je rozwiązywać, nie wspominając o tym, że niewłaściwie użyty stworzy kolejny stos kodu kotła, który będzie wymagał przyszłej konserwacji.

W rzeczywistości, jeśli coś zwrócone z metody może być null i kod wywołujący musi podjąć decyzję o tym, powinno być wcześniejsze wywołanie, które zapewnia stan.

Należy również pamiętać, że null obiekt wzorzec będzie głodny pamięci, jeśli zostanie użyty bez opieki. W tym celu - instancja obiektu NullObject powinna być współdzielona między właścicielami, a nie być pojedynczą instancją dla każdego z nich.

Również nie polecam używania tego wzorca, gdzie typ ma być prymitywną reprezentacją typu-jak byty matematyczne, które nie są skalarami: wektory, macierze, liczby zespolone i obiekty POD( Plain Old Data), które mają trzymać stan w postaci wbudowanych typów Javy. W tym drugim przypadku wywołanie metod getter z dowolnymi wynikami. Na przykład co powinno NullPerson.zwraca metodę getName ()?

Warto rozważyć takie przypadki, aby uniknąć absurdalnych rezultatów.

 14
Author: luke1985,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-04 11:24:57
  1. nigdy nie inicjalizuj zmiennych NA null.
  2. Jeśli (1) nie jest możliwe, zainicjalizuj wszystkie kolekcje i tablice do pustych kolekcji/tablic.

Robiąc to w swoim własnym kodzie i można tego uniknąć != null checks.

Większość sprawdzeń null wydaje się chronić pętle nad kolekcjami lub tablicami, więc po prostu zainicjalizuj je puste, nie będziesz potrzebował żadnych sprawdzeń null.

// Bad
ArrayList<String> lemmings;
String[] names;

void checkLemmings() {
    if (lemmings != null) for(lemming: lemmings) {
        // do something
    }
}



// Good
ArrayList<String> lemmings = new ArrayList<String>();
String[] names = {};

void checkLemmings() {
    for(lemming: lemmings) {
        // do something
    }
}

Jest w tym malutki narzut, ale warto za czystszy kod i mniej NullPointerExceptions.

 13
Author: Stuart Axon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-02 13:50:54

Jest to najczęstszy błąd występujący u większości deweloperów.

Mamy na to wiele sposobów.

Podejście 1:

org.apache.commons.lang.Validate //using apache framework

NotNull (Object object, String message)

Podejście 2:

if(someObject!=null){ // simply checking against null
}

Podejście 3:

@isNull @Nullable  // using annotation based validation

Podejście 4:

// by writing static method and calling it across whereever we needed to check the validation

static <T> T isNull(someObject e){  
   if(e == null){
      throw new NullPointerException();
   }
   return e;
}
 13
Author: Sireesh Yarlagadda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-24 17:13:41
public static <T> T ifNull(T toCheck, T ifNull) {
    if (toCheck == null) {
           return ifNull;
    }
    return toCheck;
}
 10
Author: tltester,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-19 17:17:55