Groovy - 异常处理

任何编程语言都需要异常处理来处理运行时错误,以便维持应用程序的正常流程。

异常通常会破坏应用程序的正常流程,这就是我们需要在应用程序中使用异常处理的原因。

例外情况大致分为以下几类 −

  • Checked Exception − 除了 RuntimeException 和 Error 之外,扩展 Throwable 类的类称为已检查异常,例如 IOException、SQLException 等。已检查异常在编译时进行检查。

一个经典案例是 FileNotFoundException。 假设您的应用程序中有以下代码,该代码从 E 盘中的文件中读取。

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

如果文件(file.txt)不在 E 盘中,则会引发以下异常。

Caught: java.io.FileNotFoundException: E:\file.txt (The system cannot find the file specified).

java.io.FileNotFoundException: E:\file.txt (The system cannot find the file specified).

  • Unchecked Exception − 扩展 RuntimeException 的类称为未经检查的异常,例如 ArithmeticException、NullPointerException、ArrayIndexOutOfBoundsException 等。未经检查的异常不在编译时检查,而是在运行时检查。

当您尝试访问大于数组长度的数组索引时,会发生 ArrayIndexOutOfBoundsException。 以下是此类错误的典型示例。

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

执行上述代码时,将引发以下异常。

Caught: java.lang.ArrayIndexOutOfBoundsException: 5

java.lang.ArrayIndexOutOfBoundsException: 5

  • Error − 错误是不可恢复的,例如 OutOfMemoryError、VirtualMachineError、AssertionError 等。

这些是程序永远无法恢复的错误,会导致程序崩溃。

下图显示了 Groovy 中异常的层次结构是如何组织的。 这一切都基于 Java 中定义的层次结构。

异常的层次结构

Catching Exceptions

方法使用 trycatch 关键字的组合来捕获异常。 在可能产生异常的代码周围放置了一个 try/catch 块。

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

所有可能引发异常的代码都放在受保护的代码块中。

在 catch 块中,您可以编写自定义代码来处理您的异常,以便应用程序可以从异常中恢复。

让我们看一下我们上面看到的类似代码的示例,用于访问索引值大于数组大小的数组。 但这次让我们将代码包装在 try/catch 块中。

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

当我们运行上面的程序时,会得到下面的结果 −

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