Kategorie szkoleń | Egzaminy | Kontakt
  • 1
  • 0
  • 62

Proszę o podpowiedź dlaczego wykonanie kodu powoduje:

run:

true
Exception in thread "main" java.lang.NullPointerException
    at new2015_01_21.MyBoolean. myMethod(MyBoolean.java:20)
    at new2015_01_21.MyBoolean.main(MyBoolean.java:15)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)

KOD:

class MyBoolean {

  Boolean bool[] = new Boolean[5];                      // 10 

  public static void main(String[] args) {
    Boolean [] bool = {true, true, false, true, false}; // 13
    System.out.println(bool[1]);                        // 14
    new MyBoolean().myMethod();                         // 15
    System.out.println(bool[1]);
  }

  public void myMethod() {
    if (bool[1] == true) {                              // 20
      System.out.println("It's true");
    } else {
      System.out.println("It's false");
    }
  }
}
 
 
Uczestnik szkolenia
  • Zapytał
  • @ Uczestnik szkolenia | 28.01.2015

Odpowiedź (1)

  • 0

 

Problem leży w tym, że mamy tu dwie różne deklaracje tablic bool.

 

Jedna, znajdująca się w wierszu 13, jest lokalna wewnątrz metody main i ta jest zainicjowana wartościami {true, true, false, true, false}. Metoda println (w wierszu 14) powinna więc wypisać true.

 

Dalej mamy wywołanie metody myMethod. Metoda jest bezargumentowa, więc nie ma sposobu na  przekazanie do niej naszej zainicjowanej tablicy. W efekcie referencja bool wewnątrz metody (wiersz 20) odnosi się do atrybutu klasy (p. wiersz 10).
 
Druga deklaracja - tablica na poziomie klasy - jest utworzona jako tablica 5-elementowa. Tablice w Javie automatycznie są inicjalizowane wartościami domyślnymi. Ponieważ elementy tablicy są typu obiektowego (typ Boolean, a nie boolean), więc są tam wpisane null'e.

 

Problem występuje w wierszu 20 przy porównaniu: bool[1] == true.
Tu działa niejawnie unboxing (aby porównywane wartości były tego samego typu) i na referencji bool[1] (która aktualnie ma wartość null) następuje próba wypakowania wartości logicznej (niejawnie wywoływana jest metoda bool[1].booleanValue()), a to powoduje wyrzucenie wyjątku NullPointerException.
 
Problem nie pojawiłby się, gdyby:
  • w metodzie main odwołać się do atrybutu klasy, a nie tworzyć zmienną lokalną lub
  • umożliwić przekazanie tablicy do metody myMethod poprzez parametr
  • Odpowiedział
  • @ | 28.01.2015
  • TRENER MODERATOR ALTKOM AKADEMII