logo

Excepció de punter nul a Java

En aquest tutorial, aprendrem l'excepció del punter nul a Java. L'excepció de punter nul és una excepció en temps d'execució. Null és un tipus especial de valor que es pot assignar a la referència d'un objecte. Sempre que s'intenta utilitzar una referència que tingui el valor Null, es genera l'excepció NullPointerException.

Diferents escenaris per a l'excepció del punter nul

Observeu alguns dels escenaris següents en què es pot generar l'excepció NullPointerException.

  • Calcular la mida o la longitud del null com si fos una matriu d'elements.

Nom de l'arxiu: ThrowNullExcep.java

 public class ThrowNullExcep { // main method public static void main(String args[]) { int arr[] = null; // array is assigned a null value System.out.println('The length of the array arr is: ' + arr.length); } } 

Sortida:

Excepció al fil 'principal' java.lang.NullPointerException: no es pot llegir la longitud de la matriu perquè '' és nul a ThrowNullExcep.main(ThrowNullExcep.java:7)
  • Crida a un mètode mitjançant l'objecte que té el valor Null.

Nom de l'arxiu: ThrowNullExcep1.java

 public class ThrowNullExcep1 { public void foo() { System.out.println('In the method foo.'); } public static void main(String args[]) { ThrowNullExcep1 obj = null; // assigning null value // invoking the method foo() obj.foo(); } } 

Sortida:

 Exception in thread 'main' java.lang.NullPointerException: Cannot invoke 'ThrowNullExcep1.foo()' because '' is null at ThrowNullExcep1.main(ThrowNullExcep1.java:13) 
  • Quan intenteu sincronitzar sobre un objecte NULL.

Nom de l'arxiu: ThrowNullExcep2.java

 // A Java program that synchronizes over a NULL object. import java.util.*; import java.io.*; // A Class that is required for sending the message class Sendr { public void sendMethod(String mssg) { System.out.println('Sending message: ' + mssg ); try { Thread.sleep(100); } catch (Exception exp) { System.out.println('Thread interrupted.' + exp); } System.out.println('
' + mssg + ' is sent'); } } // A Class that is used to send messages with the help of threads Threads class ThreadSend extends Thread { private String mssg; Sendr sendr; // Received a messge obj and the string // mssge that has to be sent ThreadSend(String mStr, Sendr obj) { mssg = mStr; sendr = obj; } public void run() { // Only a single thread is allowed to send a message // at a time. synchronized(sendr) { // synchronizing the send object sendr.sendMethod(mssg); } } } // Driver class public class ThrowNullExcep2 { // main method public static void main(String args[]) { Sendr sendObj = null; ThreadSend Sth1 = new ThreadSend( ' Hello ' , sendObj ); ThreadSend Sth2 = new ThreadSend( ' Bye Bye ' , sendObj ); // Starting the two threads of the ThreadedSend type Sth1.start(); Sth2.start(); // waiting for the threads to end try { Sth1.join(); Sth2.join(); } catch(Exception exp) { System.out.println('Interrupted : ' + exp); } } } 

Sortida:

 Exception in thread 'Thread-0' Exception in thread 'Thread-1' java.lang.NullPointerException: Cannot enter synchronized block because 'this.sendr' is null at ThreadSend.run(ThrowNullExcep2.java:42) java.lang.NullPointerException: Cannot enter synchronized block because 'this.sendr' is null at ThreadSend.run(ThrowNullExcep2.java:42) 
  • En lloc de llançar un valor, es llança Null.

Nom de l'arxiu: ThrowNullExcep3.java

 // Modifying or accessing the fields of the Null object. public class ThrowExcep3 { int a; // main method public static void main(String args[]) { // assigning a null value ThrowExcep3 obj = null; obj.a = 3; } } 

Sortida:

 Exception in thread 'main' java.lang.NullPointerException: Cannot assign field 'a' because '' is null at ThrowExcep3.main(ThrowExcep3.java:10) 

Requisit del valor NULL

Un null és un valor especial que s'utilitza a Java. Normalment s'utilitza per mostrar que no hi ha cap valor que s'està assignant a la variable de referència. Un valor nul s'utilitza principalment en la implementació d'estructures de dades com ara una llista enllaçada o un arbre. També s'utilitza en el patró Singleton.

Evitant la NullPointerException

Per evitar la NullPointerException, cal assegurar-se que la inicialització de tots els objectes es fa correctament abans de poder-los utilitzar. Quan es declara una variable de referència, s'ha de verificar que el valor nul no s'assigna a la referència abans que s'utilitzi el valor de referència per accedir al camp o mètode.

Observeu els següents problemes comuns amb la solució.

Cas 1: Comparació de cadenes amb el literal

Un dels problemes comuns inclou la comparació d'un literal amb una variable String. El literal pot ser un element d'una enumeració o d'una cadena. En lloc d'invocar el mètode des de l'objecte nul, considereu invocar-lo mitjançant el literal.

matemàtiques java.atzar

Nom de l'arxiu: NullPntrExcption.java

 import java.io.*; public class NullPntrExcption { // main method public static void main (String[] args) { // Initializing a String variable with a null value String pntr = null; // Checking if pntr.equals null or works fine. try { // The following line of code will raise the NullPointerException // It is because the pntr is null if (pntr.equals('JTP')) { System.out.print('String are the same.'); } else { System.out.print('Strinng are not the same.'); } } catch(NullPointerException e) { System.out.print('NullPointerException has been caught.'); } } } 

Sortida:

 NullPointerException has been caught. 

Ara, anem a veure com es pot evitar.

Nom de l'arxiu: NullPntrExcption1.java

 public class NullPntrExcption1 { // main method public static void main (String[] args) { // Initializing a String variable with a null value String pntr = null; // Checking if pntr.equals null or works fine. try { // Now, the following line of code will not raise the NullPointerException // It is because the string literal is invoking the equals() method if ('JTP'.equals(pntr)) { System.out.print('String are the same.'); } else { System.out.print('Strinng are not the same.'); } } catch(NullPointerException e) { System.out.print('NullPointerException has been caught.'); } } } 

Sortida:

 NullPointerException has been caught. 

Cas 2: Vigila els arguments del mètode

Primer cal comprovar els arguments del mètode per als valors nuls i després seguir amb l'execució del mètode. En cas contrari, hi ha moltes possibilitats que llanci una IllegalArgumentException i també senyali al mètode de crida que està equivocat amb els arguments que s'han passat.

Nom de l'arxiu: NullPntrExcption2.java

 // A program for demonstrating that one must // check the parameters are null or not before // using them. import java.io.*; public class NullPntrExcption2 { public static void main (String[] args) { // String st is an empty string and invoking method getLength() String st = ''; try { System.out.println(getLength(st)); } catch(IllegalArgumentException exp) { System.out.println('IllegalArgumentException has been caught.'); } // String s set to a value and invoking method getLength() st = 'JTP'; try { System.out.println(getLength(st)); } catch(IllegalArgumentException exp) { System.out.println('IllegalArgumentException has been caught.'); } // Setting st with a value null and invoking method getLength() st = null; try { System.out.println(getLength(st)); } catch(IllegalArgumentException exp) { System.out.println('IllegalArgumentException has been caught. ' + exp); } } // method taht computes the length of a string st. // It throws and IllegalArgumentException, if st is null public static int getLength(String st) { if (st == null) { throw new IllegalArgumentException('The argument can never be null.'); } return st.length(); } } 

Sortida:

 0 3 IllegalArgumentException has been caught. java.lang.IllegalArgumentException: The argument can never be null. 

Cas 3: Ús de l'operador ternari

També es pot utilitzar l'operador ternari per evitar l'excepció NullPointerException. En ternari, l'expressió booleana s'avalua primer. Si l'expressió s'avalua com a vertadera, es retorna el valor val1. En cas contrari, es retorna el val2.

Nom de l'arxiu: NullPntrExcption3.java

 // A program for demonstrating the fact that // NullPointerException can be avoided using the ternary operator. import java.io.*; public class NullPntrExcption3 { // main method public static void main (String[] args) { // Initializing String variable with null value String st = null; String mssge = (st == null) ? 'String is Null.' : st.substring(0, 5); System.out.println(mssge); // Initializing the String variable with string literal st = 'javaTpoint'; mssge = (st == null) ? '' : st.substring(0, 10); System.out.println(mssge); } } 

Sortida:

 String is Null. javaTpoint