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