Trong hướng dẫn này, chúng ta sẽ tìm hiểu về câu lệnh try catch trong Java với sự trợ giúp của các ví dụ.

Các khối try…catch trong Java được sử dụng để xử lý trường hợp ngoại lệ và ngăn ngừa việc chấm dứt bất thường của chương trình.

Đây là cú pháp của một khối try…catch trong Java.

try{
  // code
}
catch(exception) {
  // code
}

Khối try bao gồm code mà có thể tạo ra một ngoại lệ.

Khối catch bao gồm code được thực hiện khi có xảy ra một ngoại lệ bên trong khối try.

Ví dụ: khối try … catch trong Java

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Group: https://www.facebook.com/groups/cafedev.vn/
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
Pinterest: https://www.pinterest.com/cafedevvn/
YouTube: https://www.youtube.com/channel/UCE7zpY_SlHGEgo67pHxqIoA/
*/

class Main {
  public static void main(String[] args) {

    try {
      int divideByZero = 5 / 0;
      System.out.println("Rest of code in try block");
    }

    catch (ArithmeticException e) {
      System.out.println("ArithmeticException => " + e.getMessage());
    }
  }
}

Đầu ra

ArithmeticException => / by zero

Trong ví dụ trên, lưu ý dòng,

int divideByZero = 5 / 0;

Ở đây, chúng tôi đang cố gắng chia một số cho không . Trong trường hợp này, một ngoại lệ xảy ra. Do đó, chúng tôi đã đặt mã này bên trong khối try.

Khi chương trình gặp mã này, ArithmeticException xảy ra. Và, ngoại lệ được khối catch bắt và thực thi mã bên trong khối catch.

Các khối catch được chỉ thực hiện nếu có tồn tại một ngoại lệ bên trong khối try.

Lưu ý : Trong Java, chúng ta có thể sử dụng một khối try mà không cần một khối catch. Tuy nhiên, chúng ta không thể sử dụng khối catch mà không có khối try.

Khối try…finally trong Java

1. Chúng ta cũng có thể sử dụng khối try cùng với một khối finally.

Trong trường hợp này, khối finally luôn được thực thi cho dù có ngoại lệ bên trong khối try catch hay không.

Ví dụ: Java try … finally block

class Main {
  public static void main(String[] args) {
    try {
      int divideByZero = 5 / 0;
    }

    finally {
      System.out.println("Finally block is always executed");
    }
  }
}

Đầu ra

Finally block is always executed
Exception in thread "main" java.lang.ArithmeticException: / by zero
        at Main.main(Main.java:4)

Trong ví dụ trên, chúng ta đã sử dụng khối try cùng với khối finally. Chúng ta có thể thấy rằng mã bên trong khối try đang gây ra một ngoại lệ.

Tuy nhiên, mã bên trong khối finally được thực thi bất kể ngoại lệ.

2. try…catch…finally trong Java

Trong Java, chúng ta cũng có thể sử dụng khối finally sau khối try…catch. Ví dụ,

import java.io.*;

class ListOfNumbers {

  // create an integer array
  private int[] list = {5, 6, 8, 9, 2};

  // method to write data from array to a fila
  public void writeList() {
    PrintWriter out = null;

    try {
      System.out.println("Entering try statement");

      // creating a new file OutputFile.txt
      out = new PrintWriter(new FileWriter("OutputFile.txt"));

      // writing values from list array to Output.txt
      for (int i = 0; i < 7; i++) {
        out.println("Value at: " + i + " = " + list[i]);
      }
    }
    
    catch (Exception e) {
      System.out.println("Exception => " + e.getMessage());
    }
    
    finally {
      // checking if PrintWriter has been opened
      if (out != null) {
        System.out.println("Closing PrintWriter");
        // close PrintWriter
        out.close();
      }
      
      else {
        System.out.println("PrintWriter not open");
      }
    }

  }
}

class Main {
  public static void main(String[] args) {
    ListOfNumbers list = new ListOfNumbers();
    list.writeList();
  }
}

Đầu ra

Entering try statement
Exception => Index 5 out of bounds for length 5
Closing PrintWriter

Trong ví dụ trên, chúng ta đã tạo một mảng có tên danh sách và một file có tên output.txt. Ở đây, chúng ta đang cố gắng đọc dữ liệu từ mảng và lưu trữ vào file.

Lưu ý code,

for (int i = 0; i < 7; i++) {
  out.println("Value at: " + i + " = " + list[i]);
}

Ở đây, kích thước của mảng là 5 và phần tử cuối cùng của mảng là tại list[4]. Tuy nhiên, chúng tôi đang cố gắng truy cập các phần tử tại a[5] và a[6].

Do đó, code tạo ra một ngoại lệ bị khối bắt.

Vì khối finally luôn được thực thi, chúng ta đã bao gồm mã để đóng PrintWriter bên trong khối finally .

Một thực tiễn tốt là sử dụng khối finally để bao gồm code dọn dẹp quan trọng như đóng file hoặc kết nối.

Lưu ý : Có một số trường hợp khi một khối finally không thực thi:

  • Sử dụng phương thức System.exit()
  • Một ngoại lệ xảy ra trong khối finally 

3. Nhiều khối Catch

Đối với mỗi khối try, có thể có không hoặc nhiều khối catch. Nhiều khối catch cho phép chúng ta xử lý từng ngoại lệ khác nhau.

Loại đối số của mỗi khối catch cho biết loại ngoại lệ có thể được xử lý bởi nó. Ví dụ,

class ListOfNumbers {
  public int[] arr = new int[10];

  public void writeList() {

    try {
      arr[10] = 11;
    }
    
    catch (NumberFormatException e1) {
      System.out.println("NumberFormatException => " + e1.getMessage());
    }
    
    catch (IndexOutOfBoundsException e2) {
      System.out.println("IndexOutOfBoundsException => " + e2.getMessage());
    }

  }
}

class Main {
  public static void main(String[] args) {
    ListOfNumbers list = new ListOfNumbers();
    list.writeList();
  }
}

Đầu ra

IndexOutOfBoundsException => Index 10 out of bounds for length 10

Trong ví dụ này, chúng ta đã tạo một mảng số nguyên có tên là arr kích thước 10 .

Vì chỉ số mảng bắt đầu từ 0 nên phần tử cuối cùng của mảng là tại arr[9]. Lưu ý câu lệnh,

arr[10] = 11;

Ở đây, chúng ta đang cố gắng gán một giá trị cho chỉ mục 10 . Do đó, IndexOutOfBoundException xảy ra.

Khi một ngoại lệ xảy ra trong khối try,

  • Ngoại lệ được ném vào khối catch đầu tiên . Khối catch đầu tiên không xử lý một IndexOutOfBoundsException, vì vậy nó được chuyển sang khối catch tiếp theo .
  • Khối thứ hai catch trong ví dụ trên là trình xử lý ngoại lệ thích hợp vì nó xử lý một IndexOutOfBoundsException. Do đó, nó được thực thi.

4. Bắt nhiều ngoại lệ

Từ Java SE 7 trở lên, giờ đây chúng ta có thể bắt gặp nhiều loại ngoại lệ với một khối catch.

Điều này làm giảm sự trùng lặp mã và tăng tính đơn giản và hiệu quả của mã.

Mỗi loại ngoại lệ có thể được xử lý bởi khối catch được phân tách bằng thanh dọc |.

Cú pháp của nó là:

try {
  // code
} catch (ExceptionType1 | Exceptiontype2 ex) { 
  // catch block
}

Để tìm hiểu thêm, hãy truy cập Java để bắt nhiều ngoại lệ trong bài tiếp .

5. Câu lệnh thử tài nguyên trong Java

Câu lệnh try-with-resources là câu lệnh try có một hoặc nhiều khai báo tài nguyên.

Cú pháp của nó là:

try (resource declaration) {
  // use of the resource
} catch (ExceptionType e1) {
  // catch block
}

Tài nguyên là một đối tượng được đóng ở cuối chương trình. Nó phải được khai báo và khởi tạo trong câu lệnh try.

Hãy lấy một ví dụ.

try (PrintWriter out = new PrintWriter(new FileWriter("OutputFile.txt")) {
  // use of the resource
}

Câu lệnh try-with-resources còn được gọi là quản lý tài nguyên tự động . Câu lệnh này tự động đóng tất cả các tài nguyên ở cuối câu lệnh.

Để tìm hiểu thêm, hãy truy cập câu lệnh java try-with-resources trong bài tiếp.

Cài ứng dụng cafedev để dễ dàng cập nhật tin và học lập trình mọi lúc mọi nơi tại đây.

Nguồn và Tài liệu tiếng anh tham khảo:

Tài liệu từ cafedev:

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!