Tóm Tắt
Lưu ý và cách tạo ngoại lệ tự định nghĩa
Ta có thể cân nhắc việc tạo một lớp ngoại lệ tùy chỉnh riêng của ta khi:
- Kiểu ngoại lệ cài sẵn không đáp ứng yêu cầu.
- Cần phải phân biệt các ngoại lệ của ta với các ngoại lệ do các lớp được viết bởi các nhà cung cấp khác.
- Khối mã lệnh ném nhiều hơn một ngoại lệ liên quan.
Lưu ý là lớp ngoại lệ do ta tạo ra phải kế thừa từ lớp Exception.
Cú pháp như sau:
public class
<ExceptionName
>extends
Exception {}
Ví dụ:
public class
ServerException
extends
Exception
{public
ServerException
() { } // Override phương thức getMessage()@Override
public
String
getMessage
() // line 1 {return
"K
ế
t n
ố
i không thành công"
; } }
Giải thích:
ServerException là một lớp ngoại lệ do người dùng định nghĩa kế thừa từ lớp Exception có sẵn.
Phương thức getMessage() của lớp Exception đã được ghi đè trong lớp ServerException để in thông báo do người dùng định nghĩa “Kết nối không thành công”.
Ném ngoại lệ tự định nghĩa
Để sử dụng ngoại lệ do người dùng định nghĩa, một phương thức phải ném ngoại lệ vào thời gian chạy.
Ngoại lệ được chuyển tiếp lên trong ngăn xếp lời gọi và được xử lý tại nơi gọi phương thức.
Ví dụ sau sẽ giải thích cách ném một ngoại lệ tự định nghĩa:
package
solutions
;public class
ServerException
extends
Exception
{public
ServerException
() { } // Override phương thức getMessage()@Override
public
String
getMessage
() // line 1 {return
"K
ế
t n
ố
i không thành công"
; } }class
MyConnection
{String
ip
;String
port
;public
MyConnection
() { }public
MyConnection
(String
ip,String
port) {this
.ip
= ip;this
.port
= port; } // tạo một phương thức để ném ngoại lệ tự định nghĩapublic void
connectToServer
()throws
ServerException
{if
(ip
.equals("127.10.10.1"
) &&port
.equals("123456"
))System
.out.println("Đang k
ế
t n
ố
i Server …"
);else
throw new
ServerException(); // ném ngoại lệ tự định nghĩa } //Hàm main()public static void
main
(String
[] args) {MyConnection myConnection
=new
MyConnection("127.0.0.1"
,"123456"
);try
{myConnection
.connectToServer(); }catch
(ServerException
se) {System
.out.println(se.getMessage()); } } }
Giải thích:
Trong ví dụ trên, tại phương thức connectToServer(), nếu điều kiện ip.equals(“127.10.10.1”) && port.equals(“123456”) không được đáp ứng thì sẽ ném ngoại lệ ServerException là ngoại lệ do ta tự định nghĩa.
Gộp các ngoại lệ
Gộp ngoại lệ tức là bắt một ngoại lệ, gộp nó vào trong một ngoại lệ khác rồi ném ngoại lệ được gộp đó.
Gói ngoại lệ là một tính năng tiêu chuẩn trong Java từ version JDK 1.4.
Hầu hết các ngoại lệ tích hợp sẵn của Java đều có các hàm tạo có thể nhận tham số ‘cause’.
Những ngoại lệ tích hợp sẵn này cũng cung cấp phương thức getCause() sẽ trả về ngoại lệ được gộp.
Lý do chính của việc gộp ngoại lệ là để ngăn không cho ngăn xếp lời gọi biết về mọi ngoại lệ có thể có trong hệ thống.
Ngoài ra, người ta có thể không muốn các thành phần cấp cao nhất biết bất kỳ điều gì về các thành phần cấp dưới và các ngoại lệ mà chúng ném ra.
Ví dụ:
package
solutions
; // tạo lớp ngoại lệ riêngclass
CalculatorException
extends
Exception
{public
CalculatorException
() { } // hàm tạo với tham số là đối tượng Throwablepublic
CalculatorException
(Throwable
cause) {super
(cause); } // hàm tạo với tham số gồm một chuỗi thông báo và một đối tượng Throwablepublic
CalculatorException
(String
message,Throwable
cause) {super
(message, cause); } } // tạo lớp Calculatorclass
Calculator
{ // phương thức chia hai sốpublic void
divide
(int
a,int
b)throws
CalculatorException
{ // khối try-catchtry
{int
result
= a / b; // tiến hành chiaSystem
.out.println("K
ế
t qu
ả
: "
+result
); }catch
(ArithmeticException
ex) { // ném ngoại lệ gộpthrow new
CalculatorException("M
ẫ
u s
ố
ph
ả
i khác 0!"
, ex); } } } // tạo lớp TestCalculatorclass
TestCalculator
{public static void
main
(String
[] args) {try
{ // tạo đối tượng CalculatorCalculator objCalc
=new
Calculator(); // gọi phương thức divide()objCalc
.divide(10
,0
); }catch
(CalculatorException
ex) { // lấy tham số cause từ ngoại lệ gộpThrowable t
= ex.getCause(); // in thông báo và tham số causeSystem
.out.println("Error: "
+ ex.getMessage());System
.out.println("Cause: "
+t
); } } }
Kết quả thực thi:
Error: Mẫu số phải khác 0!
Cause: java.lang.ArithmeticException: / by zero