Co to jest wyjątek NullPointerException i jak to naprawić?

Oct 20 2008

Co to są wyjątki o zerowym wskaźniku ( java.lang.NullPointerException) i co je powoduje?

Jakich metod / narzędzi można użyć do określenia przyczyny, aby zapobiec przedwczesnemu zakończeniu programu przez wyjątek?

Odpowiedzi

3848 VincentRamdhanie Oct 20 2008 at 20:54

Kiedy deklarujesz zmienną odniesienia (tj. Obiekt), tak naprawdę tworzysz wskaźnik do obiektu. Weź pod uwagę następujący kod, w którym deklarujesz zmienną typu pierwotnego int:

int x;
x = 10;

W tym przykładzie zmienną xjest an, inta Java zainicjuje ją 0za Ciebie. Kiedy przypiszesz mu wartość 10w drugiej linii, twoja wartość 10zostanie zapisana w lokalizacji pamięci, do której odwołuje się x.

Ale kiedy próbujesz zadeklarować typ referencyjny , dzieje się coś innego. Weź następujący kod:

Integer num;
num = new Integer(10);

Pierwsza linia deklaruje zmienną o nazwie num, ale w rzeczywistości nie zawiera jeszcze wartości pierwotnej. Zamiast tego zawiera wskaźnik (ponieważ typ jest Integertypem referencyjnym). Ponieważ nie powiedziałeś jeszcze, na co wskazać, Java ustawia to na null, co oznacza „ Nie wskazuję na nic ”.

W drugim wierszu newsłowo kluczowe służy do tworzenia instancji (lub tworzenia) obiektu typu Integer, a zmienna wskaźnikowa numjest przypisywana do tego Integerobiektu.

NullPointerExceptionWystępuje podczas zadeklarować zmienną, ale nie utworzyć obiekt i przypisać ją do zmiennej przed próbują wykorzystać zawartość zmiennej (tzw wyłuskania ). Więc wskazujesz na coś, co w rzeczywistości nie istnieje.

Wyłuskiwanie danych zwykle ma miejsce podczas korzystania .z dostępu do metody lub pola albo używania [do indeksowania tablicy.

Jeśli spróbujesz numusunąć odwołanie PRZED utworzeniem obiektu, otrzymasz plik NullPointerException. W najbardziej trywialnych przypadkach kompilator wychwyci problem i poinformuje Cię, że " num may not have been initialized," ale czasami możesz napisać kod, który nie tworzy bezpośrednio obiektu.

Na przykład możesz mieć następującą metodę:

public void doSomething(SomeObject obj) {
   //do something to obj, assumes obj is not null
   obj.myMethod();
}

W takim przypadku nie tworzysz obiektu obj, ale raczej zakładasz, że został on utworzony przed doSomething()wywołaniem metody. Uwaga, możliwe jest wywołanie metody w następujący sposób:

doSomething(null);

W takim przypadku objjest null, a instrukcja obj.myMethod()wyrzuci plik NullPointerException.

Jeśli metoda ma na celu zrobienie czegoś z przekazanym obiektem, tak jak robi to powyższa metoda, należy zgłosić ten NullPointerExceptionbłąd, ponieważ jest to błąd programisty, a programista będzie potrzebował tych informacji do celów debugowania.

Oprócz NullPointerExceptions wyrzucanych w wyniku logiki metody, możesz również sprawdzić argumenty metody dla nullwartości i jawnie zgłosić NPE, dodając coś podobnego do następującego na początku metody:

//Throws an NPE with a custom error message if obj is null
Objects.requireNonNull(obj, "obj must not be null");

Zwróć uwagę, że dobrze jest wyraźnie wskazać w komunikacie o błędzie, który obiekt nie może być null. Zaletą przeprowadzania walidacji w ten sposób jest to, że 1) możesz zwrócić własne wyraźniejsze komunikaty o błędach i 2) w przypadku pozostałej części metody wiesz, że jeśli nie objzostanie ponownie przypisana, nie jest ona zerowa i można ją bezpiecznie usunąć.

Alternatywnie mogą wystąpić przypadki, w których celem metody nie jest wyłącznie operowanie na przekazanym obiekcie, a zatem parametr zerowy może być akceptowany. W takim przypadku należałoby sprawdzić parametr zerowy i zachowywać się inaczej. Powinieneś to również wyjaśnić w dokumentacji. Na przykład doSomething()można zapisać jako:

/**
  * @param obj An optional foo for ____. May be null, in which case 
  *  the result will be ____.
  */
public void doSomething(SomeObject obj) {
    if(obj == null) {
       //do something
    } else {
       //do something else
    }
}

Wreszcie, jak wskazać wyjątek i przyczynę za pomocą śledzenia stosu

Jakich metod / narzędzi można użyć do określenia przyczyny, aby zapobiec przedwczesnemu zakończeniu programu przez wyjątek?

Sonar z funkcją wyszukiwania błędów może wykryć NPE. Czy sonar może dynamicznie przechwytywać wyjątki wskaźnika zerowego spowodowane przez maszynę JVM

Teraz Java 14 dodała nową funkcję języka, aby pokazać główną przyczynę NullPointerException. Ta funkcja języka jest częścią komercyjnej maszyny JVM firmy SAP od 2006 r. Poniżej znajdują się 2 minuty czytania, aby zrozumieć tę niesamowitą funkcję języka.

https://jfeatures.com/blog/NullPointerException

W java 14 poniżej znajduje się przykładowy komunikat o wyjątku NullPointerException:

w wątku „main” java.lang.NullPointerException: Nie można wywołać „java.util.List.size ()”, ponieważ „list” ma wartość null

898 BilltheLizard Oct 20 2008 at 20:20

NullPointerExceptions są wyjątkami, które występują, gdy próbujesz użyć odwołania, które nie wskazuje na żadną lokalizację w pamięci (null), tak jakby odwoływało się do obiektu. Wywołanie metody w odwołaniu o wartości null lub próba uzyskania dostępu do pola odwołania o wartości null spowoduje wyzwolenie NullPointerException. Są to najczęstsze, ale inne sposoby są wymienione na stronie NullPointerExceptionjavadoc.

Prawdopodobnie najszybszym przykładowym kodem, jaki mógłbym wymyślić, aby zilustrować a, NullPointerExceptionbyłby:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

W pierwszym wierszu wewnątrz mainjawnie ustawiam Objectodniesienie objrówne null. Oznacza to, że mam odniesienie, ale nie wskazuje ono na żaden obiekt. Następnie próbuję traktować odniesienie tak, jakby wskazywało na obiekt, wywołując na nim metodę. Powoduje to, NullPointerExceptionponieważ nie ma kodu do wykonania w lokalizacji, na którą wskazuje odwołanie.

(Jest to kwestia techniczna, ale myślę, że warto o tym wspomnieć: odniesienie wskazujące na wartość null to nie to samo, co wskaźnik C, który wskazuje na nieprawidłowe miejsce w pamięci. Wskaźnik zerowy dosłownie nie wskazuje nigdzie , co jest nieco inne niż wskazując lokalizację, która okazała się nieprawidłowa.)

709 fgb Jun 08 2014 at 02:22

Co to jest wyjątek NullPointerException?

Dobrym miejscem do rozpoczęcia jest JavaDocs . Obejmują to:

Zgłaszane, gdy aplikacja próbuje użyć wartości null w przypadku, gdy obiekt jest wymagany. Obejmują one:

  • Wywołanie metody instancji obiektu o wartości null.
  • Dostęp do pola obiektu zerowego lub modyfikowanie go.
  • Przyjmowanie długości null tak, jakby była tablicą.
  • Uzyskiwanie dostępu lub modyfikowanie przedziałów wartości null tak, jakby to była tablica.
  • Rzucanie null tak, jakby to była wartość rzucana.

Aplikacje powinny zgłaszać wystąpienia tej klasy, aby wskazać inne nielegalne zastosowania obiektu o wartości null.

Jest również przypadek, że jeśli spróbujesz użyć odwołania zerowego z synchronized, spowoduje to również zgłoszenie tego wyjątku, zgodnie z JLS :

SynchronizedStatement:
    synchronized ( Expression ) Block
  • W przeciwnym razie, jeśli wartość Expression jest null, NullPointerExceptionzostanie zgłoszony a.

Jak to naprawić?

Więc masz NullPointerException. Jak to naprawić? Weźmy prosty przykład, który rzuca NullPointerException:

public class Printer {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer();
        printer.print();
    }
}

Zidentyfikuj wartości null

Pierwszym krokiem jest dokładne określenie, które wartości powodują wyjątek . W tym celu musimy przeprowadzić debugowanie. Ważne jest, aby nauczyć się czytać ślad stosu . Dzięki temu dowiesz się, gdzie został zgłoszony wyjątek:

Exception in thread "main" java.lang.NullPointerException
    at Printer.printString(Printer.java:13)
    at Printer.print(Printer.java:9)
    at Printer.main(Printer.java:19)

Tutaj widzimy, że wyjątek jest zgłaszany w linii 13. (w printStringmetodzie). Spójrz na wiersz i sprawdź, które wartości są puste, dodając instrukcje rejestrowania lub używając debugera . Dowiadujemy się, że sjest null, a wywołanie lengthmetody na nim zgłasza wyjątek. Widzimy, że program przestaje rzucać wyjątek, gdy s.length()zostanie usunięty z metody.

Prześledź, skąd pochodzą te wartości

Następnie sprawdź, skąd pochodzi ta wartość. Podążając za obiektami wywołującymi metodę, widzimy, że sjest ona przekazywana za printString(name)pomocą print()metody i this.namema wartość null.

Prześledź, gdzie należy ustawić te wartości

Gdzie jest this.nameustawione? W setName(String)metodzie. Po dłuższym debugowaniu widać, że ta metoda w ogóle nie jest wywoływana. Jeśli metoda została wywołana, sprawdź kolejność wywoływania tych metod, a metoda set nie jest wywoływana po metodzie print.

To wystarczy, aby dać nam rozwiązanie: dodaj połączenie printer.setName()przed rozmową printer.print().

Inne poprawki

Zmienna może mieć wartość domyślną (i setNamemoże uniemożliwić ustawienie jej na null):

private String name = "";

Każda metoda printlub printStringmoże sprawdzić wartość null , na przykład:

printString((name == null) ? "" : name);

Lub możesz zaprojektować klasę tak, aby name zawsze miała wartość różną od null :

public class Printer {
    private final String name;

    public Printer(String name) {
        this.name = Objects.requireNonNull(name);
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer("123");
        printer.print();
    }
}

Zobacz też:

  • Unikasz instrukcji „! = Null” w Javie?

Nadal nie mogę znaleźć problemu

Jeśli próbowałeś debugować problem i nadal nie masz rozwiązania, możesz zadać pytanie, aby uzyskać dodatkową pomoc, ale pamiętaj, aby uwzględnić to, co do tej pory próbowałeś. Jako minimum, umieść w pytaniu ślad stosu i zaznacz w kodzie ważne numery wierszy . Spróbuj też najpierw uprościć kod (patrz SSCCE ).

516 StephenC Jun 22 2014 at 09:16

Pytanie: Co powoduje NullPointerException(NPE)?

Jak powinieneś wiedzieć, typy Java są podzielone na prymitywnych typów ( boolean, intetc.) i typów referencyjnych . Typy odwołań w Javie pozwalają na użycie specjalnej wartości, nullktóra w Javie oznacza „brak obiektu”.

A NullPointerExceptionjest wyrzucane w czasie wykonywania za każdym razem, gdy twój program próbuje użyć a nulltak, jakby był prawdziwym odniesieniem. Na przykład, jeśli napiszesz to:

public class Test {
    public static void main(String[] args) {
        String foo = null;
        int length = foo.length();   // HERE
    }
}

instrukcja oznaczona „TUTAJ” spowoduje próbę uruchomienia length()metody na nullreferencji, co spowoduje wyświetlenie pliku NullPointerException.

Istnieje wiele sposobów użycia nullwartości, która spowoduje rozszerzenie pliku NullPointerException. W rzeczywistości jedyne rzeczy, które możesz zrobić z a nullbez powodowania NPE, to:

  • przypisać go do zmiennej odniesienia lub odczytać ze zmiennej odniesienia,
  • przypisać go do elementu tablicy lub odczytać z elementu tablicy (pod warunkiem, że samo odwołanie do tablicy ma wartość różną od null!),
  • przekazać go jako parametr lub zwrócić jako wynik lub
  • przetestować go przy użyciu ==lub !=operatorów, lub instanceof.

Pytanie: Jak odczytać ślad stosu NPE?

Załóżmy, że kompiluję i uruchamiam powyższy program:

$ javac Test.java $ java Test
Exception in thread "main" java.lang.NullPointerException
    at Test.main(Test.java:4)
$

Pierwsza obserwacja: kompilacja się udała! Problem w programie NIE jest błędem kompilacji. To jest błąd wykonania . (Niektóre IDE mogą ostrzegać, że twój program zawsze zgłosi wyjątek ... ale standardowy javackompilator tego nie robi).

Druga uwaga: kiedy uruchamiam program, wypisuje on dwie linijki „gobbledy-gook”. ŹLE!! To nie jest gobbledy-gook. Jest to ślad stosu ... i dostarcza ważnych informacji , które pomogą ci wyśledzić błąd w kodzie, jeśli poświęcisz trochę czasu na jego dokładne przeczytanie.

Spójrzmy więc, co mówi:

Exception in thread "main" java.lang.NullPointerException

Pierwsza linia śladu stosu zawiera kilka informacji:

  • Podaje nazwę wątku Java, w którym został zgłoszony wyjątek. W przypadku prostego programu z jednym wątkiem (takiego jak ten) będzie to „główny”. Przejdźmy dalej ...
  • Podaje pełną nazwę zgłoszonego wyjątku; tj java.lang.NullPointerException.
  • Jeśli wyjątek ma skojarzony komunikat o błędzie, zostanie on wyprowadzony po nazwie wyjątku. NullPointerExceptionjest pod tym względem nietypowe, ponieważ rzadko pojawia się komunikat o błędzie.

Druga linia jest najważniejsza w diagnozowaniu NPE.

at Test.main(Test.java:4)

To mówi nam o kilku rzeczach:

  • „at Test.main” mówi, że byliśmy w mainmetodzie Testklasy.
  • „Test.java:4” podaje nazwę pliku źródłowego klasy ORAZ informuje nas, że instrukcja, w której to się stało, znajduje się w linii 4 pliku.

Jeśli policzysz wiersze w powyższym pliku, wiersz 4 to ten, który oznaczyłem komentarzem „TUTAJ”.

Zauważ, że w bardziej skomplikowanym przykładzie, w śladzie stosu NPE będzie dużo linii. Ale możesz być pewien, że druga linia (pierwsza linia „at”) powie Ci, gdzie wyrzucono NPE 1 .

Krótko mówiąc, ślad stosu pokaże nam jednoznacznie, która instrukcja programu wyrzuciła NPE.

1 - Nie do końca prawda. Istnieją rzeczy zwane wyjątkami zagnieżdżonymi ...

Pytanie: Jak znaleźć przyczynę wyjątku NPE w moim kodzie?

To jest najtrudniejsza część. Krótką odpowiedzią jest zastosowanie logicznego wnioskowania do dowodów dostarczonych przez ślad stosu, kod źródłowy i odpowiednią dokumentację API.

Zilustrujmy najpierw prostym przykładem (powyżej). Zaczynamy od przyjrzenia się linii, o której ślad stosu poinformował nas, że wystąpił NPE:

int length = foo.length(); // HERE

Jak to może rzucić NPE?

W rzeczywistości jest tylko jeden sposób: może się to zdarzyć tylko wtedy, gdy fooma wartość null. Następnie próbujemy uruchomić tę length()metodę nulli ... BANG!

Ale (słyszę, jak mówisz) co by było, gdyby NPE został wyrzucony wewnątrz length()wywołania metody?

Cóż, gdyby tak się stało, ślad stosu wyglądałby inaczej. Pierwsza linia „at” powie, że wyjątek został zgłoszony w jakiejś linii w java.lang.Stringklasie, a linia 4 Test.javabędzie drugą linią „at”.

Więc skąd to się nullwzięło? W tym przypadku jest to oczywiste i oczywiste jest, co musimy zrobić, aby to naprawić. (Przypisz niezerową wartość do foo.)

OK, spróbujmy więc nieco trudniejszego przykładu. Będzie to wymagało pewnych logicznych dedukcji .

public class Test {

    private static String[] foo = new String[2];

    private static int test(String[] bar, int pos) {
        return bar[pos].length();
    }

    public static void main(String[] args) {
        int length = test(foo, 1);
    }
}

$ javac Test.java 
$ java Test Exception in thread "main" java.lang.NullPointerException at Test.test(Test.java:6) at Test.main(Test.java:10) $ 

Mamy więc teraz dwie linie „na”. Pierwsza dotyczy tej linii:

return args[pos].length();

a druga dotyczy tej linii:

int length = test(foo, 1);

Patrząc na pierwszą linię, jak to mogło spowodować wystąpienie NPE? Istnieją dwa sposoby:

  • Jeśli wartość barto, nullto bar[pos]wyrzuci NPE.
  • Jeśli wartość bar[pos]to, nullto wywołanie length()jej spowoduje zgłoszenie NPE.

Następnie musimy dowiedzieć się, który z tych scenariuszy wyjaśnia, co się właściwie dzieje. Zaczniemy od zbadania pierwszego:

Skąd się barbierze? Jest to parametr testwywołania metody i jeśli spojrzymy na to, jak testzostała wywołana, zobaczymy, że pochodzi ona ze foozmiennej statycznej. Ponadto możemy wyraźnie zobaczyć, że zainicjowaliśmy foowartość różną od null. To wystarczy, aby wstępnie odrzucić to wyjaśnienie. (Teoretycznie coś innego mogłoby się zmienić foo na null... ale tak się nie dzieje.)

A co z naszym drugim scenariuszem? Cóż, widzimy, że posto znaczy 1, więc to znaczy, że tak foo[1]musi być null. czy to możliwe?

Rzeczywiście jest! I to jest problem. Kiedy inicjalizujemy w ten sposób:

private static String[] foo = new String[2];

alokujemy a String[]z dwoma elementami, które są inicjalizowanenull . Po tym nie zmieniliśmy zawartości foo... tak foo[1]będzie null.

432 RakeshBurbure Oct 20 2008 at 20:21

To tak, jakbyś próbował uzyskać dostęp do obiektu, który jest null. Rozważ poniższy przykład:

TypeA objA;

W tym momencie właśnie zadeklarowałeś ten obiekt, ale nie został on zainicjowany ani utworzony . I za każdym razem, gdy spróbujesz uzyskać dostęp do dowolnej właściwości lub metody w nim, zostanie rzucona, NullPointerExceptionco ma sens.

Zobacz również poniższy przykład:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
365 nathan1138 Apr 17 2013 at 09:57

Wyjątek wskaźnika o wartości null jest generowany, gdy aplikacja próbuje użyć wartości null w przypadku, gdy obiekt jest wymagany. Obejmują one:

  1. Wywołanie metody instancji nullobiektu.
  2. Dostęp lub modyfikacja pola nullobiektu.
  3. Biorąc długość nulltak, jakby to była tablica.
  4. Uzyskiwanie dostępu do gniazd lub modyfikowanie ich nulltak, jakby to była tablica.
  5. Rzucanie, nulljakby to była wartość rzucana.

Aplikacje powinny zgłaszać wystąpienia tej klasy, aby wskazać inne nielegalne zastosowania nullobiektu.

Odniesienie: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

341 MrZebra Oct 20 2008 at 20:25

nullWskaźnik jest, że punkty do nikąd. Podczas nieprawidłowego wskaźnika p, można powiedzieć „daj mi dane w miejscu przechowywane w«p». Kiedy pto nullwskaźnik, lokalizacja przechowywane w pto nowhere, mówisz:«Daj mi dane w miejscu «znikąd»». Oczywiście nie może tego zrobić, więc rzuca null pointer exception.

Ogólnie rzecz biorąc, dzieje się tak, ponieważ coś nie zostało poprawnie zainicjowane.

329 L.G. Jun 25 2014 at 18:17

Istnieje już wiele wyjaśnień, które wyjaśniają, jak to się dzieje i jak to naprawić, ale należy również postępować zgodnie z najlepszymi praktykami, aby NullPointerExceptionw ogóle ich unikać .

Zobacz też: Lista dobrych praktyk

Dodałbym, bardzo ważne, dobrze wykorzystać finalmodyfikator. Używanie modyfikatora „final”, gdy ma to zastosowanie w Javie

Podsumowanie:

  1. Użyj finalmodyfikatora, aby wymusić dobrą inicjalizację.
  2. Unikaj zwracania wartości null w metodach, na przykład zwracania pustych kolekcji, gdy ma to zastosowanie.
  3. Użyj adnotacji @NotNulli@Nullable
  4. Szybka awaria i użyj potwierdzeń, aby uniknąć propagacji obiektów o wartości null w całej aplikacji, gdy nie powinny być puste.
  5. Najpierw użyj równości ze znanym obiektem: if("knownObject".equals(unknownObject)
  6. Wolę valueOf()ponad toString().
  7. Użyj zerowych bezpiecznych StringUtilsmetod StringUtils.isEmpty(null).
  8. Użyj Java 8 Optional jako wartości zwracanej w metodach. Klasa Optional zapewnia rozwiązanie do reprezentowania wartości opcjonalnych zamiast odwołań o wartości null.
323 ashishbhatt Jan 28 2012 at 13:45

W Javie wszystko (z wyjątkiem typów pierwotnych) ma postać klasy.

Jeśli chcesz użyć dowolnego obiektu, masz dwie fazy:

  1. Ogłosić
  2. Inicjalizacja

Przykład:

  • Deklaracja: Object object;
  • Inicjalizacja: object = new Object();

To samo dotyczy koncepcji tablicy:

  • Deklaracja: Item item[] = new Item[5];
  • Inicjalizacja: item[0] = new Item();

Jeśli nie podajesz sekcji inicjalizacyjnej, plik NullPointerExceptionArise.

322 javidpiprani Sep 24 2013 at 13:01

Wyjątek wskaźnika zerowego jest wskaźnikiem, że używasz obiektu bez inicjalizacji go.

Na przykład poniżej jest klasa studencka, która wykorzysta ją w naszym kodzie.

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Poniższy kod zawiera wyjątek wskaźnika zerowego.

public class School {

    Student student;

    public School() {
        try {
            student.getId();
        }
        catch(Exception e) {
            System.out.println("Null pointer exception");
        }
    }
}

Ponieważ używasz student, ale zapomniałeś zainicjować go tak, jak w poprawnym kodzie pokazanym poniżej:

public class School {

    Student student;

    public School() {
        try {
            student = new Student();
            student.setId(12);
            student.getId();
        }
        catch(Exception e) {
            System.out.println("Null pointer exception");
        }
    }
}
315 OscarRyz Oct 21 2008 at 03:05

W Javie wszystkie deklarowane zmienne są w rzeczywistości „odniesieniami” do obiektów (lub prymitywów), a nie samych obiektów.

Podczas próby wykonania jednej metody obiektowej odwołanie prosi żywy obiekt o wykonanie tej metody. Ale jeśli referencja odwołuje się do NULL (nic, zero, void, nada), to nie ma sposobu, aby metoda została wykonana. Następnie środowisko wykonawcze poinformuje Cię o tym, zgłaszając wyjątek NullPointerException.

Twoje odniesienie „wskazuje” na null, stąd „Null -> Pointer”.

Obiekt znajduje się w przestrzeni pamięci maszyny wirtualnej i jedynym sposobem uzyskania do niego dostępu jest użycie thisodwołań. Weź ten przykład:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

I w innym miejscu w Twoim kodzie:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Jest to ważna rzecz, o której należy wiedzieć - kiedy nie ma już odniesień do obiektu (w powyższym przykładzie, gdy referencei otherReferenceoba wskazują na wartość null), wówczas obiekt jest „nieosiągalny”. Nie ma sposobu, abyśmy mogli z nim pracować, więc ten obiekt jest gotowy do wyrzucenia elementów bezużytecznych, aw pewnym momencie maszyna wirtualna zwolni pamięć używaną przez ten obiekt i przydzieli inny.

287 Makoto May 25 2014 at 13:11

Kolejne wystąpienie a NullPointerExceptionma miejsce, gdy deklarujemy tablicę obiektów, a następnie natychmiast próbuje się wyłuskać elementy wewnątrz niej.

String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

Tej konkretnej NPE można uniknąć, jeśli kolejność porównania zostanie odwrócona; mianowicie, użyj .equalsna gwarantowanym obiekcie niezerowym.

Wszystkie elementy wewnątrz tablicy są inicjalizowane do ich wspólnej wartości początkowej ; dla dowolnego typu tablicy obiektów oznacza to, że wszystkie elementy są null.

Państwo musi zainicjować elementów tablicy przed dostępem lub ich dereferencji.

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}