Výjimka nulového ukazatele v Javě

Výjimka NullPointerException v Javě je RuntimeException. Nastane, když se program pokusí použít odkaz na objekt, který má hodnotu null. V Javě je 'null' speciální hodnota, kterou lze přiřadit k odkazům na objekt, aby indikovala absenci hodnoty.

Důvody pro výjimku nulového ukazatele

K výjimce NullPointerException dochází z následujících důvodů: 

  • Vyvolání metody z nulového objektu.
  • Přístup nebo úprava pole null objektu.
  • Vezmeme-li délku null, jako by to bylo pole.
  • Přístup nebo úprava slotů null objektů, jako by to bylo pole.
  • Vyhození null, jako by to byla hodnota Throwable.
  • Při pokusu o synchronizaci přes prázdný objekt.

Příklad:

Java
   public     class   Geeks     {          public     static     void     main  (  String  []     args  )     {          // Reference set to null      String     s     =     null  ;             System  .  out  .  println  (  s  .  length  ());         }   }   

výstup:

 Hangup (SIGHUP)   
Exception in thread 'main' java.lang.NullPointerException
at Geeks.main(Geeks.java:10)

Vysvětlení: V tomto příkladu je odkaz na řetězec 's' null. Když se program pokusí zavolat metodu length(), vyvolá výjimku NullPointerException, protože neexistuje žádný skutečný objekt.

Proč se v Javě používá null?

Hodnota null slouží jako zástupný symbol a označuje, že referenční proměnné není přiřazena žádná hodnota. Mezi běžné aplikace patří:

  • Propojené datové struktury : Představuje konec seznamu nebo větve stromu.
  • Návrhové vzory : Používá se ve vzorech, jako je vzor Null Object Pattern nebo Singleton Pattern.

Jak se vyhnout výjimce NullPointerException

Abychom se vyhnuli výjimce NullPointerException, musíme zajistit, aby byly všechny objekty správně inicializovány, než je použijeme. Když deklarujeme referenční proměnnou, musíme ověřit, že objekt není null, než si od objektů vyžádáme metodu nebo pole.

1. Použití řetězcových literálů v equals()

Velmi častý případový problém zahrnuje srovnání mezi řetězcovou proměnnou a literálem. Literál může být řetězec nebo prvek Enum. Místo vyvolání metody z objektu null zvažte její vyvolání z literálu. 

Příklad:

Java
   import     java.io.*  ;   class   Geeks     {      public     static     void     main     (  String  []     args  )     {          // Initializing String variable with null value      String     s     =     null  ;      // Checking if s.equals null      try      {      // This line of code throws NullPointerException because s is null      if     (  s  .  equals  (  'gfg'  ))      System  .  out  .  print  (  'Same'  );      else         System  .  out  .  print  (  'Not Same'  );      }      catch  (  NullPointerException     e  )      {      System  .  out  .  print  (  'NullPointerException Caught'  );      }      }   }   

Výstup
NullPointerException Caught 

Můžeme se vyhnout výjimce NullPointerException voláním rovná se na literál spíše než na objekt.

Java
   import     java.io.*  ;   class   Geeks     {      public     static     void     main     (  String  []     args  )     {          // Initializing String variable with null value      String     s     =     null  ;      // Checking if s is null using try catch      try      {      if     (  'gfg'  .  equals  (  s  ))      System  .  out  .  print  (  'Same'  );      else         System  .  out  .  print  (  'Not Same'  );         }      catch  (  NullPointerException     e  )      {      System  .  out  .  print  (  'Caught NullPointerException'  );      }      }   }   

Výstup
Not Same 

Poznámka : Vždy volat rovná se na literálu, aby se zabránilo volání metody na nulovém odkazu.

2. Kontrola argumentů metody

Před spuštěním těla nové metody bychom měli nejprve zkontrolovat její argumenty na hodnoty null a pokračovat v provádění metody pouze tehdy, když jsou argumenty správně zkontrolovány. Jinak vyvolá výjimku IllegalArgumentException a upozorní volající metodu, že něco není v pořádku s předávanými argumenty. 

Příklad:

Java
   import     java.io.*  ;   class   Geeks     {      public     static     void     main  (  String  []     args  )     {          // String s set an empty string and calling getLength()      String     s     =     ''  ;          try     {      System  .  out  .  println  (  getLength  (  s  ));      }      catch     (  IllegalArgumentException     e  )     {      System  .  out  .  println  (      'IllegalArgumentException caught'  );      }      // String s set to a value and calling getLength()      s     =     'GeeksforGeeks'  ;          try     {      System  .  out  .  println  (  getLength  (  s  ));      }      catch     (  IllegalArgumentException     e  )     {      System  .  out  .  println  (      'IllegalArgumentException caught'  );      }      // Setting s as null and calling getLength()      s     =     null  ;          try     {      System  .  out  .  println  (  getLength  (  s  ));      }      catch     (  IllegalArgumentException     e  )     {      System  .  out  .  println  (      'IllegalArgumentException caught'  );      }      }      public     static     int     getLength  (  String     s  )      {      if     (  s     ==     null  )      throw     new     IllegalArgumentException  (      'The argument cannot be null'  );          return     s  .  length  ();      }   }   

Výstup
0 13 IllegalArgumentException caught  

3. Použijte ternárního operátora

K zamezení výjimky NullPointerException lze použít ternární operátor. Nejprve je vyhodnocen booleovský výraz. Pokud je výraz pravdivý, je vrácena hodnota1, jinak je vrácena hodnota2. Pro manipulaci s nulovými ukazateli můžeme použít ternární operátor.

Příklad:

Java
   import     java.io.*  ;   class   Geeks     {      public     static     void     main  (  String  []     args  )      {      String     s     =     null  ;      String     m     =     (  s     ==     null  )     ?     ''     :     s  .  substring  (  0       5  );      System  .  out  .  println  (  m  );      s     =     'Geeksforgeeks'  ;      m     =     (  s     ==     null  )     ?     ''     :     s  .  substring  (  0       5  );      System  .  out  .  println  (  m  );      }   }   

Výstup
Geeks  

Vysvětlení : Ternární operátor pomáhá kontrolovat null a vyhnout se operacím s nulovými referencemi.

4. Použití volitelné třídy (Java 8+)

V Javě 8 byla volitelná třída zavedena jako objekt typu kontejner, který může nebo nemusí obsahovat hodnotu nenulovou. Pomáhá vyhnout se Výjimka NullPointerException nucením explicitně zpracovat případ, kdy hodnota chybí.

Příklad:

Java
   import     java.util.Optional  ;   public     class   OptionalExample     {      public     static     void     main  (  String  []     args  )     {      Optional   <  String  >     name     =     Optional  .  ofNullable  (  null  );      // Safe way to access      System  .  out  .  println  (  name  .  orElse  (  'Default Name'  ));     // prints: Default Name      }   }   

Výstup
Default Name  

Vysvětlení: Optional.ofNullable(value) zabalí hodnotu, která může být null. orElse() poskytuje nouzový režim, pokud hodnota není přítomna.