📜  Groovy-异常处理

📅  最后修改于: 2020-11-04 06:43:09             🧑  作者: Mango


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

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

例外大致分为以下几类-

  • 检查的异常-扩展Throwable类的类(RuntimeException和Error除外)称为检查的异常,例如IOException,SQLException等。检查的异常在编译时进行检查。

一种典型的情况是FileNotFoundException。假设您的应用程序中有以下代码,该代码从E驱动器中的文件读取。

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

如果E驱动器中没有文件(file.txt),则将引发以下异常。

捕获:java.io.FileNotFoundException:E:\ file.txt(系统找不到指定的文件)。

java.io.FileNotFoundException:E:\ file.txt(系统找不到指定的文件)。

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

一种经典的情况是ArrayIndexOutOfBoundsException,当您尝试访问大于数组长度的数组索引时会发生这种情况。以下是这种错误的典型示例。

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

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

捕获:java.lang.ArrayIndexOutOfBoundsException:5

java.lang.ArrayIndexOutOfBoundsException:5

  • 错误-错误是无法恢复的,例如OutOfMemoryError,VirtualMachineError,AssertionError等。

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

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

异常层次

捕捉异常

一种方法使用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(Exception ex) {
         println("Catching the exception");
      }
        
      println("Let's move on after the exception");
   }
}

当我们运行上面的程序时,我们将得到以下结果-

Catching the exception 
Let's move on after the exception

从上面的代码,我们在try块中包装了错误的代码。在catch块中,我们只是捕获我们的异常并输出一条消息,说明发生了异常。

多个捕获块

一个可以有多个catch块来处理多种类型的异常。对于每个catch块,根据引发的异常类型,您将编写相应的代码来处理它。

让我们修改上面的代码以专门捕获ArrayIndexOutOfBoundsException。以下是代码段。

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

当我们运行上面的程序时,我们将得到以下结果-

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

从上面的代码中,您可以看到ArrayIndexOutOfBoundsException catch块首先被捕获,因为这意味着异常的标准。

最终块

finally块位于try块或catch块之后。无论是否发生异常,始终都会执行一个finally代码块。

通过使用finally块,无论受保护的代码发生什么情况,您都可以运行要执行的任何清理类型的语句。下面给出了该块的语法。

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

让我们修改上面的代码并添加代码的finally块。以下是代码段。

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

当我们运行上面的程序时,我们将得到以下结果-

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

以下是Groovy中可用的Exception方法-

公共字符串getMessage()

返回有关已发生异常的详细消息。该消息在Throwable构造函数中初始化。

公共Throwable getCause()

返回由Throwable对象表示的异常原因。

公共字符串toString()

返回与getMessage()的结果串联的类的名称

公共无效printStackTrace()

将toString()的结果与堆栈跟踪一起输出到错误输出流System.err。

公共StackTraceElement [] getStackTrace()

返回一个包含堆栈跟踪中每个元素的数组。索引0处的元素表示调用堆栈的顶部,而数组中的最后一个元素表示调用堆栈底部的方法。

公共Throwable fillInStackTrace()

用当前堆栈跟踪填充此Throwable对象的堆栈跟踪,并添加到堆栈跟踪中的所有先前信息。

以下是使用上述某些方法的代码示例-

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