Groovy - Xử lý ngoại lệ
Xử lý ngoại lệ được yêu cầu trong bất kỳ ngôn ngữ lập trình nào để xử lý các lỗi thời gian chạy để có thể duy trì luồng bình thường của ứng dụng.
Ngoại lệ thường làm gián đoạn luồng thông thường của ứng dụng, đó là lý do tại sao chúng ta cần sử dụng xử lý Ngoại lệ trong ứng dụng của mình.
Các ngoại lệ được phân loại rộng rãi thành các loại sau:
Checked Exception - Các lớp mở rộng lớp Throwable ngoại trừ RuntimeException và Error được gọi là các ngoại lệ đã kiểm tra, ví dụ :IOException, SQLException, v.v. Các ngoại lệ đã kiểm tra được kiểm tra tại thời điểm biên dịch.
Một trường hợp cổ điển là FileNotFoundException. Giả sử bạn có đoạn mã sau trong ứng dụng của mình, mã này đọc từ một tệp trong ổ E.
class Example {
static void main(String[] args) {
File file = new File("E://file.txt");
FileReader fr = new FileReader(file);
}
}
nếu Tệp (file.txt) không có trong ổ E thì ngoại lệ sau sẽ được đưa ra.
Caught: java.io.FileNotFoundException: E: \ file.txt (Hệ thống không thể tìm thấy tệp được chỉ định).
java.io.FileNotFoundException: E: \ file.txt (Hệ thống không thể tìm thấy tệp được chỉ định).
Unchecked Exception - Các lớp mở rộng RuntimeException được gọi là các ngoại lệ không được kiểm tra, ví dụ: ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException, v.v. Các ngoại lệ không được kiểm tra không được kiểm tra tại thời gian biên dịch thay vì chúng được kiểm tra trong thời gian chạy.
Một trường hợp cổ điển là ArrayIndexOutOfBoundsException xảy ra khi bạn cố gắng truy cập chỉ mục của một mảng lớn hơn độ dài của mảng. Sau đây là một ví dụ điển hình của loại sai lầm này.
class Example {
static void main(String[] args) {
def arr = new int[3];
arr[5] = 5;
}
}
Khi đoạn mã trên được thực thi, ngoại lệ sau sẽ được đưa ra.
Bắt: java.lang.ArrayIndexOutOfBoundsException: 5
java.lang.ArrayIndexOutOfBoundsException: 5
Error - Lỗi không thể khôi phục được ví dụ OutOfMemoryError, VirtualMachineError, AssertionError, v.v.
Đây là những lỗi mà chương trình không bao giờ có thể khôi phục được và sẽ khiến chương trình bị sập.
Sơ đồ sau đây cho thấy cách tổ chức phân cấp các ngoại lệ trong Groovy. Tất cả đều dựa trên hệ thống phân cấp được xác định trong Java.
Bắt ngoại lệ
Một phương thức bắt một ngoại lệ bằng cách sử dụng kết hợp try và catchtừ khóa. Một khối try / catch được đặt xung quanh mã có thể tạo ra một ngoại lệ.
try {
//Protected code
} catch(ExceptionName e1) {
//Catch block
}
Tất cả mã của bạn có thể tạo ra một ngoại lệ được đặt trong khối mã được bảo vệ.
Trong khối bắt, bạn có thể viết mã tùy chỉnh để xử lý ngoại lệ của mình để ứng dụng có thể khôi phục từ ngoại lệ.
Hãy xem một ví dụ về mã tương tự mà chúng ta đã thấy ở trên để truy cập vào một mảng có giá trị chỉ mục lớn hơn kích thước của mảng. Nhưng lần này hãy gói mã của chúng ta trong một khối 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");
}
}
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:
Catching the exception
Let's move on after the exception
Từ mã trên, chúng tôi bọc mã bị lỗi trong khối thử. Trong khối bắt, chúng ta chỉ bắt ngoại lệ và xuất ra thông báo rằng một ngoại lệ đã xảy ra.
Nhiều khối bắt
Người ta có thể có nhiều khối bắt để xử lý nhiều loại ngoại lệ. Đối với mỗi khối bắt, tùy thuộc vào loại ngoại lệ được nêu ra, bạn sẽ viết mã để xử lý nó cho phù hợp.
Hãy sửa đổi mã ở trên của chúng tôi để bắt ArrayIndexOutOfBoundsException cụ thể. Sau đây là đoạn mã.
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");
}
}
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:
Catching the Aray out of Bounds exception
Let's move on after the exception
Từ đoạn mã trên, bạn có thể thấy rằng khối bắt ArrayIndexOutOfBoundsException được bắt trước vì nó có nghĩa là tiêu chí của ngoại lệ.
Cuối cùng là Chặn
Các finallykhối theo sau khối try hoặc khối catch. Một khối mã cuối cùng luôn thực thi, bất kể sự xuất hiện của Ngoại lệ.
Sử dụng khối cuối cùng cho phép bạn chạy bất kỳ câu lệnh loại dọn dẹp nào mà bạn muốn thực thi, bất kể điều gì xảy ra trong mã được bảo vệ. Cú pháp cho khối này được đưa ra dưới đây.
try {
//Protected code
} catch(ExceptionType1 e1) {
//Catch block
} catch(ExceptionType2 e2) {
//Catch block
} catch(ExceptionType3 e3) {
//Catch block
} finally {
//The finally block always executes.
}
Hãy sửa đổi mã ở trên của chúng tôi và thêm khối mã cuối cùng. Sau đây là đoạn mã.
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");
}
}
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:
Catching the Array out of Bounds exception
The final block
Let's move on after the exception
Sau đây là các phương pháp Ngoại lệ có sẵn trong Groovy:
public String getMessage ()
Trả về một thông báo chi tiết về ngoại lệ đã xảy ra. Thông báo này được khởi tạo trong phương thức khởi tạo Throwable.
public Throwable getCause ()
Trả về nguyên nhân của ngoại lệ như được đại diện bởi một đối tượng Có thể ném.
public String toString ()
Trả về tên của lớp được nối với kết quả của getMessage ()
public void printStackTrace ()
In kết quả của toString () cùng với dấu vết ngăn xếp vào System.err, luồng đầu ra lỗi.
public StackTraceElement [] getStackTrace ()
Trả về một mảng chứa từng phần tử trên dấu vết ngăn xếp. Phần tử ở chỉ số 0 đại diện cho phần trên cùng của ngăn xếp cuộc gọi và phần tử cuối cùng trong mảng đại diện cho phương thức ở cuối ngăn xếp cuộc gọi.
public Throwable fillInStackTrace ()
Làm đầy dấu vết ngăn xếp của đối tượng Có thể ném này bằng dấu vết ngăn xếp hiện tại, thêm vào bất kỳ thông tin nào trước đó trong dấu vết ngăn xếp.
Thí dụ
Sau đây là ví dụ mã sử dụng một số phương pháp được đưa ra ở trên:
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");
}
}
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:
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