Java: Ngoại lệ tự định nghĩa
Giải phóng thời gian, khai phóng năng lực
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ĩa public 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êng class CalculatorException extends Exception { public CalculatorException() { } // hàm tạo với tham số là đối tượng Throwable public 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 Throwable public CalculatorException(String message, Throwable cause) { super(message, cause); } } // tạo lớp Calculator class Calculator { // phương thức chia hai số public void divide(int a, int b) throws CalculatorException { // khối try-catch try { int result = a / b; // tiến hành chia System.out.println("Kết quả: " + result); } catch (ArithmeticException ex) { // ném ngoại lệ gộp throw new CalculatorException("Mẫu số phải khác 0!", ex); } } } // tạo lớp TestCalculator class TestCalculator { public static void main(String[] args) { try { // tạo đối tượng Calculator Calculator 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ộp Throwable t = ex.getCause(); // in thông báo và tham số cause System.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
Giải phóng thời gian, khai phóng năng lực