Java: Ngoại lệ tự định nghĩa


Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên

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

» Tiếp: KIỂM TRA KIẾN THỨC EXCEPTION
« Trước: throw và throws
Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên
Copied !!!