Groovy - การจัดการข้อยกเว้น

จำเป็นต้องมีการจัดการข้อยกเว้นในภาษาการเขียนโปรแกรมใด ๆ เพื่อจัดการกับข้อผิดพลาดรันไทม์เพื่อให้สามารถรักษาขั้นตอนปกติของแอปพลิเคชันได้

โดยปกติข้อยกเว้นจะขัดขวางขั้นตอนปกติของแอปพลิเคชันซึ่งเป็นเหตุผลว่าทำไมเราจึงต้องใช้การจัดการข้อยกเว้นในแอปพลิเคชันของเรา

ข้อยกเว้นแบ่งออกเป็นประเภทกว้าง ๆ ดังนี้ -

  • Checked Exception - คลาสที่ขยายคลาส Throwable ยกเว้น RuntimeException และ Error เรียกว่าข้อยกเว้นที่ตรวจสอบเช่น EGIOException, 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 (ระบบไม่พบไฟล์ที่ระบุ)

java.io.FileNotFoundException: E: \ file.txt (ระบบไม่พบไฟล์ที่ระบุ)

  • Unchecked Exception - คลาสที่ขยาย 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

  • Error - ข้อผิดพลาดไม่สามารถกู้คืนได้เช่น OutOfMemoryError, VirtualMachineError, AssertionError เป็นต้น

สิ่งเหล่านี้เป็นข้อผิดพลาดที่โปรแกรมไม่สามารถกู้คืนได้และจะทำให้โปรแกรมหยุดทำงาน

แผนภาพต่อไปนี้แสดงวิธีการจัดลำดับชั้นของข้อยกเว้นใน Groovy ทั้งหมดขึ้นอยู่กับลำดับชั้นที่กำหนดไว้ใน Java

การจับข้อยกเว้น

เมธอดจับข้อยกเว้นโดยใช้การรวมกันของ try และ catchคำหลัก บล็อก 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

จากรหัสด้านบนเราสรุปรหัสที่ผิดพลาดในบล็อกลอง ในบล็อก catch เราเพิ่งตรวจจับข้อยกเว้นของเราและแสดงข้อความว่ามีข้อยกเว้นเกิดขึ้น

หลาย Catch Blocks

หนึ่งสามารถมีหลายบล็อกเพื่อจัดการกับข้อยกเว้นหลายประเภท สำหรับแต่ละบล็อกจับขึ้นอยู่กับประเภทของข้อยกเว้นที่เพิ่มขึ้นคุณจะต้องเขียนโค้ดเพื่อจัดการตามนั้น

มาแก้ไขโค้ดด้านบนของเราเพื่อจับ 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 block ถูกจับได้ก่อนเนื่องจากหมายถึงเกณฑ์ของข้อยกเว้น

สุดท้ายบล็อก

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. 
}

มาแก้ไขโค้ดด้านบนของเราและเพิ่มบล็อคโค้ดในที่สุด ต่อไปนี้เป็นข้อมูลโค้ด

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 -

String สาธารณะ getMessage ()

ส่งคืนข้อความโดยละเอียดเกี่ยวกับข้อยกเว้นที่เกิดขึ้น ข้อความนี้เริ่มต้นในตัวสร้าง Throwable

getCause สาธารณะโยนได้ ()

ส่งคืนสาเหตุของข้อยกเว้นที่แสดงโดยวัตถุ Throwable

สาธารณะ String toString ()

ส่งคืนชื่อของคลาสที่เชื่อมต่อกับผลลัพธ์ของ getMessage ()

โมฆะสาธารณะ printStackTrace ()

พิมพ์ผลลัพธ์ของ toString () พร้อมกับการติดตามสแต็กไปยัง System.err สตรีมเอาต์พุตข้อผิดพลาด

StackTraceElement สาธารณะ [] getStackTrace ()

ส่งคืนอาร์เรย์ที่มีแต่ละองค์ประกอบบนการติดตามสแต็ก องค์ประกอบที่ดัชนี 0 แสดงถึงส่วนบนสุดของ call stack และองค์ประกอบสุดท้ายในอาร์เรย์แสดงถึงวิธีการที่ด้านล่างของ call stack

สาธารณะ 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