Excepció de punter nul a Java

Una NullPointerException a Java és una RuntimeException. Es produeix quan un programa intenta utilitzar una referència d'objecte que té el valor nul. A Java, "nul" és un valor especial que es pot assignar a les referències d'objectes per indicar l'absència d'un valor.

Motius de l'excepció del punter nul

Una NullPointerException es produeix pels motius següents: 

  • Invocació d'un mètode des d'un objecte nul.
  • Accés o modificació del camp d'un objecte nul.
  • Prenent la longitud de null com si fos una matriu.
  • Accedir o modificar les ranures d'objectes nuls com si fos una matriu.
  • Llançar null com si fos un valor Throwable.
  • Quan intenteu sincronitzar sobre un objecte nul.

Exemple:

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

Sortida:

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

Explicació: En aquest exemple, la referència de cadena 's' és nul·la. Quan el programa intenta cridar el mètode length() llança una NullPointerException perquè no hi ha cap objecte real.

Per què s'utilitza null a Java?

El valor nul serveix com a marcador de posició i indica que no s'assigna cap valor a una variable de referència. Les aplicacions habituals inclouen:

  • Estructures de dades enllaçades : representa el final d'una llista o branca d'arbre.
  • Patrons de disseny : S'utilitza en patrons com el patró d'objecte nul o el patró Singleton.

Com evitar NullPointerException

Per evitar la NullPointerException ens hem d'assegurar que tots els objectes s'inicialitzin correctament abans d'utilitzar-los. Quan declarem una variable de referència hem de verificar que l'objecte no és nul abans de demanar un mètode o un camp als objectes.

1. Utilitzar literals de cadena en equals()

Un problema de cas molt comú implica la comparació entre una variable String i un literal. El literal pot ser una cadena o un element d'una enumeració. En lloc d'invocar el mètode des de l'objecte nul, considereu invocar-lo des del literal. 

Exemple:

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'  );      }      }   }   

Sortida
NullPointerException Caught 

Podem evitar NullPointerException cridant a equals en literal en lloc d'objecte.

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'  );      }      }   }   

Sortida
Not Same 

Nota : invoqueu sempre iguals al literal per evitar cridar un mètode en una referència nul·la.

2. Comprovació dels arguments del mètode

Abans d'executar el cos del nou mètode, primer hauríem de comprovar els seus arguments per als valors nuls i continuar amb l'execució del mètode només quan els arguments estiguin correctament comprovats. En cas contrari, llançarà una IllegalArgumentException i notificarà al mètode de crida que hi ha alguna cosa malament amb els arguments passats. 

Exemple:

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  ();      }   }   

Sortida
0 13 IllegalArgumentException caught  

3. Utilitzeu l'operador ternari

L'operador ternari es pot utilitzar per evitar NullPointerException. Primer s'avalua l'expressió booleana. Si l'expressió és certa, es retorna el valor1, en cas contrari es retorna el valor2. Podem utilitzar l'operador ternari per manejar punters nuls.

Exemple:

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  );      }   }   

Sortida
Geeks  

Explicació : l'operador ternari ajuda a comprovar si hi ha nul·les i a evitar operacions sobre referències nul·les.

4. Ús de la classe opcional (Java 8+)

A Java 8, la classe opcional es va introduir com un objecte contenidor que pot contenir o no un valor no nul. Ajuda a evitar NullPointerException forçant a gestionar explícitament el cas quan no hi ha un valor.

Exemple:

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      }   }   

Sortida
Default Name  

Explicació: Optional.ofNullable(valor) embolcalla el valor que pot ser nul. o Else() proporciona una alternativa si el valor no està present.