任何編程語言都需要異常處理來處理運(yùn)行時(shí)錯(cuò)誤,從而可以保持應(yīng)用程序的正常流程。
異常通常會(huì)破壞應(yīng)用程序的正常流程,這就是為什么我們需要在我們的應(yīng)用程序中使用異常處理的原因。
例如大致分為以下類別 -
檢測(cè)異常 -擴(kuò)展Throwable類(除了RuntimeException和Error)的類稱為檢查異常egIOException,SQLException等。檢查的異常在編譯時(shí)檢查。
一個(gè)典型的情況是FileNotFoundException。假設(shè)您的應(yīng)用程序中有以下代碼,它從E盤中的文件讀取。
class Example { static void main(String[] args) { File file = new File("E://file.txt"); FileReader fr = new FileReader(file); } }
如果文件(file.txt)不在E盤中,那么將引發(fā)以下異常。
抓?。簀ava.io.FileNotFoundException:E:\ file.txt(系統(tǒng)找不到指定的文件)。
java.io.FileNotFoundException:E:\ file.txt(系統(tǒng)找不到指定的文件)。
未經(jīng)檢查的異常 -擴(kuò)展RuntimeException的類稱為未檢查異常,例如,ArithmeticException,NullPointerException,ArrayIndexOutOfBoundsException等。未檢查的異常在編譯期不檢查,而是在運(yùn)行時(shí)檢查。
一個(gè)典型的情況是ArrayIndexOutOfBoundsException,當(dāng)您嘗試訪問大于數(shù)組長度的數(shù)組的索引時(shí),會(huì)發(fā)生這種情況。以下是這種錯(cuò)誤的典型例子。
class Example { static void main(String[] args) { def arr = new int[3]; arr[5] = 5; } }
當(dāng)上面的代碼執(zhí)行時(shí),將引發(fā)以下異常。
抓取:java.lang.ArrayIndexOutOfBoundsException:5
java.lang.ArrayIndexOutOfBoundsException:5
錯(cuò)誤 -錯(cuò)誤無法恢復(fù)。 OutOfMemoryError,VirtualMachineError,AssertionError等。
這些是程序永遠(yuǎn)不能恢復(fù)的錯(cuò)誤,將導(dǎo)致程序崩潰。
下圖顯示了如何組織Groovy中的異常層次結(jié)構(gòu)。它都基于Java中定義的層次結(jié)構(gòu)。
方法使用try和catch關(guān)鍵字的組合捕獲異常。 try / catch塊放置在可能生成異常的代碼周圍。
try { //Protected code } catch(ExceptionName e1) { //Catch block }
所有可能引發(fā)異常的代碼都放在受保護(hù)的代碼塊中。
在catch塊中,您可以編寫自定義代碼來處理異常,以便應(yīng)用程序可以從異常中恢復(fù)。
讓我們看一個(gè)類似的代碼示例,我們?cè)谏厦婵吹揭粋€(gè)索引值大于數(shù)組大小的數(shù)組。但這次讓我們將我們的代碼包裝在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"); } }
當(dāng)我們運(yùn)行上面的程序,我們將得到以下結(jié)果 -
Catching the exception Let's move on after the exception
從上面的代碼,我們?cè)趖ry塊中包裝錯(cuò)誤的代碼。在catch塊中,我們只是捕獲我們的異常并輸出一個(gè)異常已經(jīng)發(fā)生的消息。
可以有多個(gè)catch塊來處理多種類型的異常。對(duì)于每個(gè)catch塊,根據(jù)引發(fā)的異常的類型,您將編寫代碼來相應(yīng)地處理它。
讓我們修改上面的代碼來具體捕捉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"); } }
當(dāng)我們運(yùn)行上面的程序,我們將得到以下結(jié)果 -
Catching the Aray out of Bounds exception Let's move on after the exception
從上面的代碼,你可以看到ArrayIndexOutOfBoundsException catch塊首先被捕獲,因?yàn)樗馕吨惓5臉?biāo)準(zhǔn)。
finally塊跟在try塊或catch塊之后。代碼的finally塊總是執(zhí)行,而不管異常的發(fā)生。
使用finally塊可以運(yùn)行任何你想要執(zhí)行的清除類型語句,無論在受保護(hù)代碼中發(fā)生什么。該塊的語法如下。
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"); } }
當(dāng)我們運(yùn)行上面的程序,我們將得到以下結(jié)果 -
Catching the Array out of Bounds exception The final block Let's move on after the exception
以下是Groovy中提供的異常方法 -
返回有關(guān)已發(fā)生異常的詳細(xì)消息。此消息在Throwable構(gòu)造函數(shù)中初始化。
返回由Throwable對(duì)象表示的異常原因。
返回與getMessage()的結(jié)果連接的類的名稱。
將toString()的結(jié)果與堆棧跟蹤一起打印到System.err,錯(cuò)誤輸出流。
返回包含堆棧跟蹤上的每個(gè)元素的數(shù)組。索引0處的元素表示調(diào)用堆棧的頂部,數(shù)組中的最后一個(gè)元素表示調(diào)用堆棧底部的方法。
使用當(dāng)前堆棧跟蹤填充此Throwable對(duì)象的堆棧跟蹤,添加到堆棧跟蹤中的任何以前的信息。
下面是使用上面給出的一些方法的代碼示例 -
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"); } }
當(dāng)我們運(yùn)行上面的程序,我們將得到以下結(jié)果 -
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
更多建議: