Groovy - obsługa wyjątków

Obsługa wyjątków jest wymagana w każdym języku programowania, aby obsłużyć błędy w czasie wykonywania, aby można było zachować normalny przepływ aplikacji.

Wyjątki zwykle zakłócają normalny przepływ aplikacji, co jest powodem, dla którego musimy korzystać z obsługi wyjątków w naszej aplikacji.

Wyjątki są ogólnie podzielone na następujące kategorie -

  • Checked Exception - Klasy rozszerzające klasę Throwable z wyjątkiem RuntimeException i Error są znane jako sprawdzone wyjątki, np .IOException, SQLException itp. Zaznaczone wyjątki są sprawdzane w czasie kompilacji.

Jednym z klasycznych przypadków jest wyjątek FileNotFoundException. Załóżmy, że masz w aplikacji następujący kod, który czyta z pliku na dysku E.

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

jeśli pliku (file.txt) nie ma na dysku E, zostanie zgłoszony następujący wyjątek.

Złapany: java.io.FileNotFoundException: E: \ file.txt (system nie może znaleźć określonego pliku).

java.io.FileNotFoundException: E: \ file.txt (System nie może znaleźć określonego pliku).

  • Unchecked Exception - Klasy, które rozszerzają RuntimeException są znane jako niezaznaczone wyjątki, np. ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException itp. Niezaznaczone wyjątki nie są sprawdzane w czasie kompilacji, ale są sprawdzane w czasie wykonywania.

Jednym z klasycznych przypadków jest wyjątek ArrayIndexOutOfBoundsException, który ma miejsce, gdy próbujesz uzyskać dostęp do indeksu tablicy, który jest większy niż długość tablicy. Poniżej znajduje się typowy przykład tego rodzaju błędu.

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

Gdy powyższy kod zostanie wykonany, zostanie zgłoszony następujący wyjątek.

Złapany: java.lang.ArrayIndexOutOfBoundsException: 5

java.lang.ArrayIndexOutOfBoundsException: 5

  • Error - Błąd jest nieodwracalny, np. OutOfMemoryError, VirtualMachineError, AssertionError itp.

Są to błędy, z których program nigdy nie może odzyskać i które spowodują awarię programu.

Poniższy diagram pokazuje, jak zorganizowana jest hierarchia wyjątków w Groovy. Wszystko opiera się na hierarchii zdefiniowanej w Javie.

Łapanie wyjątków

Metoda przechwytuje wyjątek przy użyciu kombinacji try i catchsłowa kluczowe. Blok try / catch jest umieszczany wokół kodu, który może generować wyjątek.

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

Cały kod, który może zgłosić wyjątek, jest umieszczany w bloku kodu chronionego.

W bloku catch można napisać niestandardowy kod do obsługi wyjątku, tak aby aplikacja mogła odzyskać dane po wyjściu.

Spójrzmy na przykład podobnego kodu, który widzieliśmy powyżej, aby uzyskać dostęp do tablicy z wartością indeksu, która jest większa niż rozmiar tablicy. Ale tym razem zawińmy nasz kod w blok 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");
   }
}

Po uruchomieniu powyższego programu otrzymamy następujący wynik -

Catching the exception 
Let's move on after the exception

Z powyższego kodu zawijamy błędny kod w bloku try. W bloku catch po prostu przechwytujemy nasz wyjątek i wyświetlamy komunikat, że wystąpił wyjątek.

Wiele bloków połowowych

Można mieć wiele bloków catch do obsługi wielu typów wyjątków. Dla każdego bloku catch, w zależności od typu zgłoszonego wyjątku, napisałbyś kod, aby odpowiednio go obsłużyć.

Zmodyfikujmy powyższy kod, aby wychwycić wyjątek ArrayIndexOutOfBoundsException. Poniżej znajduje się fragment kodu.

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

Po uruchomieniu powyższego programu otrzymamy następujący wynik -

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

Z powyższego kodu widać, że blok catch ArrayIndexOutOfBoundsException jest przechwytywany jako pierwszy, ponieważ oznacza to kryteria wyjątku.

Wreszcie Block

Plik finallyblok następuje po bloku try lub bloku catch. Ostateczny blok kodu zawsze jest wykonywany, niezależnie od wystąpienia wyjątku.

Korzystanie z bloku last umożliwia uruchamianie dowolnych instrukcji typu czyszczenia, które chcesz wykonać, bez względu na to, co dzieje się w chronionym kodzie. Składnię tego bloku podano poniżej.

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

Zmodyfikujmy powyższy kod i dodajmy ostatni blok kodu. Poniżej znajduje się fragment kodu.

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

Po uruchomieniu powyższego programu otrzymamy następujący wynik -

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

Poniżej znajdują się metody wyjątków dostępne w Groovy -

public String getMessage ()

Zwraca szczegółowy komunikat o wystąpieniu wyjątku. Ta wiadomość jest inicjowana w konstruktorze Throwable.

public Throwable getCause ()

Zwraca przyczynę wyjątku reprezentowaną przez obiekt Throwable.

public String toString ()

Zwraca nazwę klasy połączoną z wynikiem getMessage ()

public void printStackTrace ()

Wyświetla wynik metody toString () wraz ze śladem stosu do System.err, strumienia wyjściowego błędu.

public StackTraceElement [] getStackTrace ()

Zwraca tablicę zawierającą każdy element ze śladu stosu. Element pod indeksem 0 reprezentuje górę stosu wywołań, a ostatni element w tablicy reprezentuje metodę na dole stosu wywołań.

public Throwable fillInStackTrace ()

Wypełnia ślad stosu tego obiektu Throwable bieżącym śladem stosu, dodając do wszelkich poprzednich informacji w śladzie stosu.

Przykład

Poniżej znajduje się przykład kodu wykorzystujący niektóre z metod podanych powyżej -

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

Po uruchomieniu powyższego programu otrzymamy następujący wynik -

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