Java: 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

throw và throws

Đôi khi có thể có được yêu cầu một phương thức chuyển điều khiển lên trên ngăn xếp lời gọi để xử lý ngoại lệ.

Ví dụ: trong khi thực hiện kết nối với máy chủ, có thể không đoán trước loại định dạng mà id máy chủ sẽ được cung cấp bởi người dùng.

Trong trường hợp này, không nên bắt ngoại lệ mà nên cho phép một phương thức ở trên ngăn xếp lời gọi xử lý nó.

Nếu một phương thức không bắt được các ngoại lệ đã kiểm tra có thể xảy ra bên trong nó, thì nó phải chỉ định rằng nó có thể ném các ngoại lệ này.

Mệnh đề throws được viết sau tên phương thức và danh sách đối số và trước dấu ngoặc nhọn mở ({) của phương thức.

Ví dụ sau đây thể hiện phương thức writeToFile() với mệnh đề throws:

PrintWriter objPwOut=null;
public void writeToFile() throws FileNotFoundException{
  //...
}

Nền tảng Java cung cấp một số lớp ngoại lệ là con của lớp Throwable.

Các lớp này cho phép các chương trình phân biệt giữa các loại ngoại lệ khác nhau có thể xảy ra trong quá trình thực thi chương trình.

Tất cả các phương thức sử dụng câu lệnh throw để ném một ngoại lệ.

Câu lệnh throw nhận một đối số duy nhất là một đối tượng của lớp Throwable.

Các đối tượng của Throwable là các thể hiện của bất kỳ lớp con nào của lớp Throwable.

Trong ví dụ sau, phương thức writeToFile() được thực hiện để throw ngoại lệ FileNotFoundException:

import java.io.*;
public class FileWriting {
  PrintWriter objPwOut = null;
  // Khai báo ngoi l trong mnh đ throws
  public void writeToFile() throws FileNotFoundException {
    try {
      objPwOut = new PrintWriter("C:\\MyFile.txt");
    } catch (FileNotFoundException ex) {
      // Ném li ngoi l      throw new FileNotFoundException();
    } finally { if (objPwOut != null) {
      objPwOut.close();
      System.out.println("PrintWriter closed"); }
    }
  }
  public static void main(String[] args) {
    try{
      FileWriting fw = new FileWriting();
      fw.writeToFile();
    } catch(FileNotFoundException ex){
      // Bt ngoi l      System.out.println("File does not Exist " + ex.getMessage()); }
    }
  }
}

Giải thích ví dụ:

  • FileNotFoundException bị chặn bởi khối catch của phương thức writeToFile().
  • Tuy nhiên, ngoại lệ không được xử lý trong khối này, mà được ném trở lại bằng cách sử dụng câu lệnh throw new FileNotFoundException().
  • Do đó, ngoại lệ được chuyển tiếp lên trong ngăn xếp lời gọi. Bây giờ, nơi gọi phương thức writeToFile() sẽ phải xử lý ngoại lệ này.
  • Vì main() là phương thức gọi (nơi gọi) nên ngoại lệ sẽ phải được xử lý ở main().
  • Do đó, một khối catch cho FileNotFoundException đã được cung cấp trong phương thức main() nơi ngoại lệ sẽ được xử lý.

Ném trực tiếp ngoại lệ

Ta có thể ném trực tiếp các ngoại lệ khỏi một phương thức và chuyển nó đến một phương thức cao hơn trong hệ thống phân cấp.

Ví dụ sau đây thể hiện điều này:

package v1study.com;

class Calculator {
  public void divide(int a, int b) throws ArithmeticException {
    if (b == 0) {
      throw new ArithmeticException(); // ngoi l được ném trc tiếp
    }
    int result = a / b;
    System.out.println("Kết qu: " + result);
  }
}

public class TestCalculator {
  public static void main(String[] args) {
    try {
      Calculator objCalc = new Calculator();
      // Gi phương thc divide()
      objCalc.divide(5, 0);
    } catch (ArithmeticException ex) {
      System.out.println("Mu s phi khác 0");
    }
  }
}

Xử lý nhiều ngoại lệ trong một khối catch

Java cung cấp tính năng xử lý nhiều hơn một ngoại lệ trong một khối catch duy nhất.

Tính năng này giúp giảm trùng lặp mã lệnh và ngăn chặn việc sử dụng một ngoại lệ tổng quát hóa nhiều lần.

Các ngoại lệ đặt trong một khối catch được phân tách bằng dấu xổ đứng (|) như cú pháp sau:

catch (ExceptionType1 | ExceptionType2 ex | ...) {
  // các câu lnh
}

Ví dụ:

package solutions;

public class demo {
  static void calculate() throws ArithmeticException,ArrayIndexOutOfBoundsException {
    float div, sum = 0;
    float marks[] = {10, 30, 50, 70, 90};
    for (int i = 0; i < marks.length - 1; i++) {
      if (marks[i + 1] == 0) { //dòng 1
        throw new ArithmeticException("Li chia cho 0!");
      }
      div = marks[i] / marks[i + 1];
      System.out.println("Kết qu phép chia: " + div);
    }
    for (int i = 0; i < marks.length + 1; i++) {
      if (i >= marks.length) { //dòng 2
        throw new ArrayIndexOutOfBoundsException("Ch s vượt quá gii hn!");
      }
      sum += marks[i];
    }
    System.out.println("Tng là: " + sum);
  }

  public static void main(String[] args) {
    try {
      calculate();
    } catch (ArrayIndexOutOfBoundsException | ArithmeticException ex) {
      // Bt nhiu ngoi l      System.out.println("Có li: " + ex.getMessage());
    }
  }
}

Kết quả hiển thị như sau:

Kết quả phép chia: 0.33333334
Kết quả phép chia: 0.6
Kết quả phép chia: 0.71428573
Kết quả phép chia: 0.7777778
Có lỗi: Chỉ số vượt quá giới hạn!

» Tiếp: Ngoại lệ tự định nghĩa
« Trước: Ưu điểm của ngoại lệ
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 !!!