NỘI DUNG BÀI HỌC

✳️ Bắt lỗi ngoại lệ trong Java là gì?
✳️ Cách sử dụng Try Catch trong Java
✳️ Các loại Exception trong Java

✅ Bắt lỗi ngoại lệ trong Java là gì?

Khi chạy chương trình, có rất nhiều loại lỗi khác nhau có thể xảy ra như: lỗi do sai lầm người viết, lỗi do sai thông tin đầu vào hoặc những lỗi mà không thể lường trước được. Và khi có lỗi, Java sẽ dừng lại và hiển thị thông tin lỗi ra, kĩ thuật đó thường được gọi là "throw an exception/error".

Ví dụ chương trình Java sẽ ném lỗi như sau:



Lỗi trên có thể nhấn Ctrl S mà nó dính chữ "s" vào trong giá trị tham số của hàm chẳng hạn 😆. Và có những lỗi xuất phát từ người dùng, thì lúc đó ta không thể cho họ xem thông tin lỗi như thế này được. Với những người không thành thạo về máy vi tính hoặc tiếng Anh thì họ nghĩ chương trình bạn viết bị lỗi mà không phải lỗi từ họ.

Vì vậy, Try Catch có nhiệm vụ bắt (Catch) các lỗi mà thực tế có thể xảy ra để xử lý sao cho chương trình thân thiện với người dùng hơn.


✅ Cách sử dụng Try Catch trong Java


🔆 Khi nào cần sử dụng try catch

Khi thực thi một đoạn code Java nào đó, các lỗi khác nhau có thể xảy ra như:

  • Lỗi do chính coder tạo ra
  • Lỗi cú pháp
  • Lỗi logic
  • ... những điều mà chúng ta có thể không lường trước.


Ví dụ như:

  • Người dùng nhập dữ liệu không hợp lệ
  • Truy cập vượt quá chỉ số mảng
  • Chia một số cho 0
  • ……


Khi xảy ra lỗi, ngoại lệ, Java thông thường sẽ dừng thực thi chương trình và đưa ra một thông báo, hay nói cách khác là Java ném ra một exception – Ngoại lệ.

🔆 Xử lý ngoại lệ trong Java

Xử lý ngoại lệ (Exception Handling) trong java là một cơ chế xử lý các lỗi runtime để có thể duy trì luồng bình thường của ứng dụng.

Quá trình xử lý exception được gọi là catch exception (bắt ngoại lệ), nếu Runtime System không xử lý được ngoại lệ thì chương trình sẽ kết thúc.

Khối lệnh try trong java được sử dụng để chứa một đoạn code thực thi mà có thế trong quá trình thực thi nó sẽ xảy ra một ngoại lệ.

Sau một khối lệnh try, bạn phải khai báo khối lệnh catch hoặc finally, hoặc cả hai.

Khối catch trong java được sử dụng để xử lý nếu xảy ra Exception, nếu không thì nó bị bỏ qua.

Khối catch phải được sử dụng ngay sau khối try. Bạn có thể sử dụng nhiều khối catch với nhưng chỉ có một khối try duy nhất.

🔆 Cú pháp của try catch trong Java

try {
    // code có thể ném ra ngoại lệ
} catch(Exception_class_Name ex) {
    // code xử lý ngoại lệ
}

 

🔆 Cú pháp của try finally trong Java

try {
    // code có thể ném ra ngoại lệ
} finally {
    // code trong khối này luôn được thực thi
}
 

🔆 Cú pháp của try catch finally trong Java

try {
    // code có thể ném ra ngoại lệ
} catch(Exception_class_Name_1 ex) {
    // code xử lý ngoại lệ 1
} catch(Exception_class_Name_2 ex) {
    // code xử lý ngoại lệ 2
} catch(Exception_class_Name_n ex) {
    // code xử lý ngoại lệ n
} finally {
    // code trong khối này luôn được thực thi
}

 

✳️ Ví dụ về cách sử dụng try catch trong java

Ở phần này mình sẽ giới thiệu cho các bạn một số ví dụ để các bạn làm quen với try catch trong Java nhé.


Tuy nhiên, đầu tiên, nếu chúng ta không sử dụng try catch, hãy thử chạy một đoạn code lỗi sau, xem trình biên dịch sẽ báo như thế nào nhé.

public class TryCatchDemo1 {
    public static void main(String[] args) {
        int data = 5 / 0;
        System.out.println("Phép chia cho 0");
    }
}

 

Và đây là kết quả:
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at Bai17_TryCatch.TryCatchDemo1.main(TryCatchDemo1.java:5)

 

Trình biên dịch đã dừng lại ngay tại dòng int data = 5 / 0 và ném ra một ngoại lệ (exception) ở trong màn hình console.

Lúc này dòng System.out.println("Phép chia cho 0"); chưa được thực thi.

Sau đây chúng ta sử dụng try catch để xử lý ngoại lệ chia cho số 0 trên xem sao nhé.


🔆 Ví dụ 1: Sử dụng try catch trong Java (với chỉ một khối catch)

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

        //Xử lý ngoại lệ bằng try catch trong Java
        try {
            int data = 5 / 0;
        } catch (ArithmeticException e) {
            //In ra màn hình tên ngoại lệ
            System.out.println(e);
        }
        System.out.println("Phép chia cho 0");
    }
}

Và đây là kết quả:

java.lang.ArithmeticException: / by zero
Phép chia cho 0

 

Nếu như bình thường (giống ở ví dụ trên) thì lẽ ra chia một số cho số 0 thì chương trình Java sẽ gặp lỗi và dừng thực thi.

=> Câu lệnh sau đó System.out.println("Phép chia cho 0"); sẽ không bao giờ được thực thi.

Nhưng ở đây, cho dù gặp lỗi chia cho số 0 nhưng câu lệnh sau đó vẫn được thực thi.

Điều này chứng tỏ rằng, try catch đã làm việc thành công. Nó đã bắt được ngoại lệ và tiếp tục thực thi dòng chảy bình thường của chương trình.

Tiếp theo, chúng ta có thể sử dụng nhiều khối lệnh catch như ví dụ sau:


🔆 Ví dụ 2: Sử dụng try catch trong Java (với nhiều khối catch)

Trước tiên, bạn hãy đọc qua ví dụ ở dưới đây và xem kết quả. Mình sẽ giải thích ví dụ này sau:

public class TryCatchDemo2 {
    public static void main(String[] args) {
        try {
            int arr[] = new int[5];
            arr[6] = 4;
            System.out.println("arr[6 = " + arr[6]);

            int data = 0;
            int div = 10 / data;
            System.out.println("Average = " + div);

            String obj = null;
            System.out.println(obj.length());
        } catch (NullPointerException ex) {
            System.out.println(ex);
        } catch (ArithmeticException ex) {
            System.out.println(ex);
        } catch (ArrayIndexOutOfBoundsException ex) {
            System.out.println(ex);
        }

        System.out.println("Finished!");
    }
}

 

Kết quả:

java.lang.ArrayIndexOutOfBoundsException: Index 6 out of bounds for length 5
Finished!


Ở ví dụ này, mình thử tạo một mảng với 5 phần tử.

Mình biết rõ là Java không cho phép truy cập vào phần tử không tồn tại trong mảng. Nhưng mình vẫn làm để cho nó xảy ra lỗi (Sau đó sẽ bắt ngoại lệ ArrayIndexOutOfBoundsException)

Tiếp theo nữa, mình cố gắng tạo ra một lỗi NullPointerException và một lỗi toán học (lỗi chia cho số 0)

Sau đó mình ném tất cả code thực thi vào khối try.

Ngay sau đó, mình lần lượt tạo ra các khối catch để bắt từng loại ngoại lệ mà mình nghĩ rằng trong quá trình thực thi sẽ xảy ra.

Lưu ý: Khi bắt gặp một ngoại lệ, trình biên dịch Java sẽ ngay lập tức thực thi xử lý ngoại lệ tương ứng (do đó, nó thoát khỏi khối try và không tìm thấy 2 ngoại lệ khác mà mình đã cố tạo ra)

🔆 Ví dụ 3: Sử dụng try finally trong Java (ngoại lệ xảy ra nhưng không được xử lý)

Ở ví dụ này, mình thử bắt ngoại lệ với khối catch, nhưng mình sẽ bắt ngoại lệ không đúng.

public class TryCatchDemo3 {
    public static void main(String[] args) {
        try {
            int data = 5 / 0;
        } catch (NullPointerException ex) {
            System.out.println(ex);
        } finally {
            System.out.println("Khối lệnh finally luôn được thực thi");
        }
        System.out.println("Finished!");
    }
}

Kết quả:
Khối lệnh finally luôn được thực thi
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at Bai17_TryCatch.TryCatchDemo3.main(TryCatchDemo3.java:6)​
 
Và cũng ví dụ này, nhưng mình thử không sử dụng khối catch:

public class TryCatchDemo3 {
    public static void main(String[] args) {
        try {
            int data = 5 / 0;
        } finally {
            System.out.println("Khối lệnh finally luôn được thực thi");
        }
        System.out.println("Finished!");
    }
}​

Bạn thử chạy chương trình trên xem kết quả như thế nào?

Như phần đầu đã trình bày thì khối finally luôn luôn được thực hiện dù có xảy ra ngoại lệ hay không.


Trong ví dụ trên, ngoại lệ có xảy ra nhưng mình cố tình bắt sai mã ngoại lệ, đúng ra phải là ArithmeticException chứ không phải là NullPointerException.

Do đó ngoại lệ vẫn xảy ra vì chưa bắt đúng, nhưng dòng System.out.println("Khối lệnh finally luôn được thực thi"); vẫn được thực thi và in ra màn hình, trong khi chương trình đã stop, không thực thi câu lệnh System.out.println("Finished!");

🔆 Ví dụ 4: Sử dụng try finally trong Java và nơi ngoại lệ xảy ra và được xử lý

Cũng tương tự ví dụ trên, nhưng lần này mình sẽ bắt đúng ngoại lệ.

public class TryCatchDemo4 {
    public static void main(String[] args) {
        try {
            int data = 5 / 0;
        } catch (ArithmeticException ex) {
            System.out.println(ex);
        } finally {
            System.out.println("Khối lệnh finally luôn được thực thi");
        }
        System.out.println("Finished!");
    }
}

Kết quả:
java.lang.ArithmeticException: / by zero
Khối lệnh finally luôn được thực thi
Finished!​

 Nhìn vào ví dụ này, các bạn thấy đó, cho dù có bắt đúng ngoại lệ hay không thì khối finally cũng luôn được thực thi.
 

✅ Các loại Exception trong Java

Có 2 kiểu ngoại lệ trong Java:

  • Checked Exceptions: Các ngoại lệ này thường là bị buộc phải bắt hoặc khai báo. Nếu quy tắc này không được tuân theo thì trình biên dịch sẽ không thực thi chương trình.
  • Unchecked Exceptions: Ngoại lệ này thường là do viết code sai, truyền đối null hoặc tham số không chính xác...

 

🔆 Các ngoại lệ kiểu Checked Exceptions phổ biến:

  • IOException: Ngoại lệ liên quan đến file input / output
  • SQLException: Ngoại lệ liên quan đến cú pháp SQL
  • DataAccessException: Ngoại lệ liên quan đến việc truy cập CSDL
  • ClassNotFoundException: Bị ném khi JVM không thể tìm thấy một lớp mà nó cần, do lỗi dòng lệnh, sự cố đường dẫn hoặc tệp, class bị thiếu...
  • InstantiationException: Ngoại lệ khi cố gắng tạo đối tượng của một abstract class hoặc interface



🔆 Các ngoại lệ kiểu Unchecked Exceptions phổ biến

  • NullPointerException: Ngoại lệ bị ném ra khi cố gắng truy cập một đối tượng có biến tham chiếu có giá trị hiện tại là null
  • ArrayIndexOutOfBound: Ngoại lệ khi cố gắng truy cập một phần tử vượt quá độ dài của mảng
  • IllegalArgumentException: Ngoại lệ bị ném ra khi một phương thức nhận được một đối số được định dạng khác với phương thức mong đợi.
  • IllegalStateException: Ngoại lệ bị ném ra khi trạng thái của môi trường không phù hợp với hoạt động cố gắng thực hiện, ví dụ: Sử dụng Scanner đã bị đóng.
  • NumberFormatException: Ngoại lệ bị ném khi một phương thức chuyển đổi một Chuỗi thành số nhưng không thể chuyển đổi.
  • ArithmeticException: Lỗi số học, chẳng hạn như chia cho 0.

 

Teacher

Teacher

Anh Tester

Software Quality Engineer

Đường dẫu khó chân vẫn cần bước đi
Đời dẫu khổ tâm vẫn cần nghĩ thấu

Cộng đồng Automation Testing Việt Nam:

🌱 Telegram Automation Testing:   Cộng đồng Automation Testing
🌱 
Facebook Group Automation: Cộng đồng Automation Testing Việt Nam
🌱 
Facebook Fanpage: Cộng đồng Automation Testing Việt Nam - Selenium
🌱 Telegram
Manual Testing:   Cộng đồng Manual Testing
🌱 
Facebook Group Manual: Cộng đồng Manual Testing Việt Nam

Chia sẻ khóa học lên trang

Bạn có thể đăng khóa học của chính bạn lên trang Anh Tester để kiếm tiền

Danh sách bài học