Groovy - Gestione delle eccezioni

La gestione delle eccezioni è richiesta in qualsiasi linguaggio di programmazione per gestire gli errori di runtime in modo da poter mantenere il normale flusso dell'applicazione.

L'eccezione normalmente interrompe il normale flusso dell'applicazione, motivo per cui dobbiamo utilizzare la gestione delle eccezioni nella nostra applicazione.

Le eccezioni sono generalmente classificate nelle seguenti categorie:

  • Checked Exception - Le classi che estendono la classe Throwable eccetto RuntimeException ed Error sono note come eccezioni controllate egIOException, SQLException ecc. Le eccezioni selezionate vengono verificate in fase di compilazione.

Un caso classico è FileNotFoundException. Supponi di avere il seguente codice nella tua applicazione che legge da un file nell'unità E.

class Example {
   static void main(String[] args) {
      File file = new File("E://file.txt");
      FileReader fr = new FileReader(file);
   } 
}

se il File (file.txt) non è presente nell'unità E, verrà sollevata la seguente eccezione.

Catturato: java.io.FileNotFoundException: E: \ file.txt (il sistema non riesce a trovare il file specificato).

java.io.FileNotFoundException: E: \ file.txt (il sistema non riesce a trovare il file specificato).

  • Unchecked Exception - Le classi che estendono RuntimeException sono note come eccezioni non controllate, ad esempio, ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException ecc. Le eccezioni non controllate non vengono controllate in fase di compilazione, piuttosto vengono controllate in fase di esecuzione.

Un caso classico è ArrayIndexOutOfBoundsException che si verifica quando si tenta di accedere a un indice di un array che è maggiore della lunghezza dell'array. Di seguito è riportato un tipico esempio di questo tipo di errore.

class Example {
   static void main(String[] args) {
      def arr = new int[3];
      arr[5] = 5;
   } 
}

Quando il codice precedente viene eseguito, verrà sollevata la seguente eccezione.

Catturato: java.lang.ArrayIndexOutOfBoundsException: 5

java.lang.ArrayIndexOutOfBoundsException: 5

  • Error - L'errore è irrecuperabile, ad esempio OutOfMemoryError, VirtualMachineError, AssertionError ecc.

Questi sono errori da cui il programma non potrà mai ripristinarsi e causeranno il crash del programma.

Il diagramma seguente mostra come è organizzata la gerarchia delle eccezioni in Groovy. È tutto basato sulla gerarchia definita in Java.

Catturare le eccezioni

Un metodo rileva un'eccezione utilizzando una combinazione di try e catchparole chiave. Un blocco try / catch viene posizionato attorno al codice che potrebbe generare un'eccezione.

try { 
   //Protected code 
} catch(ExceptionName e1) {
   //Catch block 
}

Tutto il codice che potrebbe sollevare un'eccezione viene inserito nel blocco di codice protetto.

Nel blocco catch è possibile scrivere codice personalizzato per gestire l'eccezione in modo che l'applicazione possa eseguire il ripristino dall'eccezione.

Diamo un'occhiata a un esempio del codice simile che abbiamo visto sopra per accedere a un array con un valore di indice maggiore della dimensione dell'array. Ma questa volta racchiudiamo il nostro codice in un blocco try / catch.

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      } catch(Exception ex) {
         println("Catching the exception");
      }
		
      println("Let's move on after the exception");
   }
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Catching the exception 
Let's move on after the exception

Dal codice sopra, inseriamo il codice difettoso nel blocco try. Nel blocco catch stiamo solo catturando la nostra eccezione e inviando un messaggio che si è verificata un'eccezione.

Blocchi multipli di cattura

Si possono avere più blocchi catch per gestire più tipi di eccezioni. Per ogni blocco catch, a seconda del tipo di eccezione sollevata, dovresti scrivere codice per gestirlo di conseguenza.

Modifichiamo il nostro codice sopra per catturare specificamente l'eccezione ArrayIndexOutOfBoundsException. Di seguito è riportato lo snippet di codice.

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      }catch(ArrayIndexOutOfBoundsException ex) {
         println("Catching the Array out of Bounds exception");
      }catch(Exception ex) {
         println("Catching the exception");
      }
		
      println("Let's move on after the exception");
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Catching the Aray out of Bounds exception 
Let's move on after the exception

Dal codice sopra puoi vedere che il blocco catch ArrayIndexOutOfBoundsException viene catturato per primo perché indica i criteri dell'eccezione.

Infine Block

Il finallyil blocco segue un blocco try o un blocco catch. Un blocco di codice infine viene sempre eseguito, indipendentemente dal verificarsi di un'eccezione.

L'utilizzo di un blocco finalmente consente di eseguire qualsiasi istruzione di tipo cleanup che si desidera eseguire, indipendentemente da ciò che accade nel codice protetto. La sintassi per questo blocco è fornita di seguito.

try { 
   //Protected code 
} catch(ExceptionType1 e1) { 
   //Catch block 
} catch(ExceptionType2 e2) { 
   //Catch block 
} catch(ExceptionType3 e3) { 
   //Catch block 
} finally {
   //The finally block always executes. 
}

Modifichiamo il nostro codice sopra e aggiungiamo il blocco di codice finalmente. Di seguito è riportato lo snippet di codice.

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      } catch(ArrayIndexOutOfBoundsException ex) {
         println("Catching the Array out of Bounds exception");
      }catch(Exception ex) {
         println("Catching the exception");
      } finally {
         println("The final block");
      }
		
      println("Let's move on after the exception");
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

Catching the Array out of Bounds exception 
The final block 
Let's move on after the exception

Di seguito sono riportati i metodi di eccezione disponibili in Groovy:

public String getMessage ()

Restituisce un messaggio dettagliato sull'eccezione che si è verificata. Questo messaggio viene inizializzato nel costruttore Throwable.

getCause lanciabili public ()

Restituisce la causa dell'eccezione rappresentata da un oggetto Throwable.

public String toString ()

Restituisce il nome della classe concatenato con il risultato di getMessage ()

public void printStackTrace ()

Stampa il risultato di toString () insieme alla traccia dello stack su System.err, il flusso di output dell'errore.

public StackTraceElement [] getStackTrace ()

Restituisce un array contenente ogni elemento nella traccia dello stack. L'elemento all'indice 0 rappresenta la parte superiore dello stack di chiamate e l'ultimo elemento dell'array rappresenta il metodo in fondo allo stack di chiamate.

public Throwable fillInStackTrace ()

Riempie la traccia dello stack di questo oggetto Throwable con la traccia dello stack corrente, aggiungendosi a qualsiasi informazione precedente nella traccia dello stack.

Esempio

Di seguito è riportato l'esempio di codice che utilizza alcuni dei metodi sopra indicati:

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      }catch(ArrayIndexOutOfBoundsException ex) {
         println(ex.toString());
         println(ex.getMessage());
         println(ex.getStackTrace());  
      } catch(Exception ex) {
         println("Catching the exception");
      }finally {
         println("The final block");
      }
		
      println("Let's move on after the exception");
   } 
}

Quando eseguiamo il programma sopra, otterremo il seguente risultato:

java.lang.ArrayIndexOutOfBoundsException: 5 
5 
[org.codehaus.groovy.runtime.dgmimpl.arrays.IntegerArrayPutAtMetaMethod$MyPojoMetaMet 
hodSite.call(IntegerArrayPutAtMetaMethod.java:75), 
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) ,
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) ,
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133) ,
Example.main(Sample:8), sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ,
java.lang.reflect.Method.invoke(Method.java:606),
org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93),
groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325),
groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1443),
org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:893),
groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:287),
groovy.lang.GroovyShell.run(GroovyShell.java:524),
groovy.lang.GroovyShell.run(GroovyShell.java:513),
groovy.ui.GroovyMain.processOnce(GroovyMain.java:652),
groovy.ui.GroovyMain.run(GroovyMain.java:384),
groovy.ui.GroovyMain.process(GroovyMain.java:370),
groovy.ui.GroovyMain.processArgs(GroovyMain.java:129),
groovy.ui.GroovyMain.main(GroovyMain.java:109),
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ,
java.lang.reflect.Method.invoke(Method.java:606),
org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:109),
org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:131),
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ,
java.lang.reflect.Method.invoke(Method.java:606),
com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)]
 
The final block 
Let's move on after the exception