26/05/2018, 16:41

Ngoại lệ và xử lý Ngoại lệ trong Java

Khi ngoại lệ trong Java xảy ra, khiến luồng chuẩn của chương trình bị gián đoạn và chương trình / ứng dụng sẽ chấm dứt bất thường. Vì vậy bạn cần tìm hiểu nguyên ...

Khi ngoại lệ trong Java xảy ra, khiến luồng chuẩn của chương trình bị gián đoạn và chương trình / ứng dụng sẽ chấm dứt bất thường. Vì vậy bạn cần tìm hiểu nguyên nhân xảy ra ngoại lệ và xử lý ngoại lệ trong Java

ngoai le va xu ly ngoai le trong java

Ngoại lệ trong Java

Có nhiều nguyên nhân xảy ra ngoại lệ trong Java, bao gồm:

- Người dùng nhập dữ liệu không hợp lệ.
- Không tìm thấy file cần mở.
- Kết nối mạng bị mất trong quá trình thực hiện giao tiếp hoặc JVM hết bộ nhớ.

Một số ngoại lệ xảy ra có thể là do lỗi của người dùng, một số do lỗi của lập trình viên và số khác là do lỗi của nguồn dữ liệu vật lý.

Dựa trên đó, chúng ta có 3 loại ngoại lệ khác nhau. Tất cả những gì mà bạn cần là tìm hiểu các ngoại lệ để biết cách xử lý chúng trong Java.

- Checked exception: Là ngoại lệ xảy ra trong thời gian biên dịch, chúng còn được gọi là ngoại lệ thời gian biên dịch. Các ngoại lệ biên dịch này không thể bỏ qua dễ dàng tại thời điểm biên dịch, vì vậy lập trình viên nên quan tâm đến việc xử lý các ngoại lệ này.

Ví dụ, nếu sử dụng lớp FileReader trong chương trình để đọc dữ liệu từ 1 file, nếu file được chỉ định trong constructor không tồn tại sẽ xảy ra FileNotFoundException và trình biên dịch sẽ thông báo cho lập trình viên xử lý ngoại lệ này.

Ví dụ:

ngoai le va xu ly ngoai le trong java 2

Nếu cố gắng biên dịch chương trình trên, bạn sẽ nhận được ngoại lệ dưới đây:

C:>javac FilenotFound_Demo.java

FilenotFound_Demo.java:8: error: unreported exception FileNotFoundException; must be caught or declared to be thrown

FileReader fr = new FileReader(file);

^

1 error

Lưu ý: Vì các phương thức read() và close() của lớp FileReader ném IOException, bạn có thể quan sát các thông báo trình biên dịch để xử lý IOException, cùng FileNotFoundException.

- Unchecked exception: Là ngoại lệ xảy ra vào thời điểm thực thi, nó còn được gọi là Runtime Exception. Ngoại lệ này bao gồm các lỗi lập trình, ví dụ như lỗi logic hoặc lỗi sử dụng API không đúng cách. Runtime Exception được bỏ qua tại thời điểm biên dịch.

Ví dụ nếu khai báo mảng 5 phần tử trong chương trình và bạn cố gắng gọi phần tử thứ 6 của mảng, thì ngoại lệ ArrayIndexOutOfBoundsExceptionexception sẽ xảy ra.

Ví dụ:

ngoai le va xu ly ngoai le trong java 3

Nếu biên dịch và thực thi chương trình trên, bạn sẽ nhận được ngoại lệ dưới đây:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5

at Exceptions.Unchecked_Demo.main(Unchecked_Demo.java:8)

- Error: Nó không giống các ngoại lệ, nhưng vấn đề phát sinh vượt quá quyền kiểm soát của người dùng hoặc lập trình viên. Error được bỏ qua trong mã vì bạn hiếm khi có thể làm gì đó khi chương trình bị error. Ví dụ nếu lỗi tràn bộ đệm xảy ra, lỗi sẽ phát sinh. Error cũng bị bỏ qua tại thời điểm biên dịch.

Phân cấp ngoại lệ (exception) trong Java

Tất cả các lớp ngoại lệ là lớp con của lớp java.lang.Exception. Lớp ngoại lệ là lớp con của lớp Throwable. Một loại lớp ngoại lệ khác là Error cũng là lớp con của lớp Throwable.

Error là các điều kiện bất thường xảy ra trong trường hợp lỗi nghiêm trọng, không được các chương trình Java xử lý. Error được tạo ra để biểu diễn lỗi được tạo ra trong môi trường runtime. Ví dụ: JVM đã hết bọ nhớ. Thông thường các chương trình không thể khôi phục từ các lỗi.

Lớp ngoại lệ có 2 lớp con chính là: IOException và RuntimeException.

Dưới đây là danh sách các ngoại lệ Checked exception và Unchecked exception có sẵn trong Java:

ngoai le va xu ly ngoai le trong java 4

Các phương thức trong ngoại lệ trong Java

Dưới đây là bảng danh sách các phương thức quan trọng có sẵn trong lớp Throwable trong Java:

ngoai le va xu ly ngoai le trong java 5

Xử lý ngoại lệ trong Java

Khối catch trong ngoại lệ

Phương thức catch là một ngoại lệ sử dụng kết hợp từ khóa try và catch. Một khối try / catch được đặt xung quanh mã có thể tạo ra một ngoại lệ. Mã bên trong khối try / catch được gọi là mã được bảo vệ. Dưới đây là cú pháp để sử dụng khối try / catch:

Cú pháp

try {

// Protected code

} catch (ExceptionName e1) {

// Catch block

}

Mã dễ bị ngoại lệ được đặt trong khối try. Khi một ngoại lệ xảy ra, ngoại lệ đó sẽ được khối catch liên kết với nó xử lý. Mỗi khối try lập tức theo sau một khối catch hoặc khối finally.

Một lệnh catch khai báo kiểu ngoại lệ mà bạn đang cố gắng xử lý. Nếu ngoại lệ xảy ra trong mã bảo vệ, khối catch theo sau try sẽ được kiểm tra. Nếu kiểu ngoại lệ xảy ra được liệt kê trong khối catch, ngoại lệ được chuyển đến khối catch như một tham số được truyền vào tham số phương thức.

Ví dụ:

Dưới đây là khai báo mảng với 2 phần tử. Mã cố gắng truy cập phần tử thứ 3 của mảng và tạo ra ngoại lệ:

ngoai le va xu ly ngoai le trong java 6

Ví dụ trên trả về kết quả đầu ra là:

Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3

Out of the block

Dùng try có nhiều catch trong Java

Một khối try có thể đi kèm nhiều khối catch.

Cú pháp nhiều khối catch có dạng như dưới đây:

try {

// Protected code

} catch (ExceptionType1 e1) {

// Catch block

} catch (ExceptionType2 e2) {

// Catch block

} catch (ExceptionType3 e3) {

// Catch block

}

Các câu lệnh trên biểu diễn 3 khối catch, nhưng bạn có thể thêm nhiều khối khác sau try. Nếu ngoại lệ xảy ra trong mã bảo vệ, ngoại lệ được ném vào khối catch đầu tiên trong danh sách.

Nếu kiểu dữ liệu của ngoại lệ phù hợp với ExceptionType1, nó sẽ bị bắt tại đó. Nếu không, ngoại lệ được chuyển xuống lệnh catch thứ 2 và tiếp tục cho đến khi ngoại lệ bị bắt hoặc thất bại thông qua tất cả các catch, trong trường hợp này phương thức hiện tại sẽ ngừng thực thi và ngoại lệ được ném vào phương thức trước trên call stack.

Ví dụ:

Dưới đây là đoạn mã hiển thị cách sử dụng nhiều lệnh try / catch:

ngoai le va xu ly ngoai le trong java 7

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

Kể từ Java 7, bạn có thể xử lý nhiều ngoại lệ bằng cách sử dụng một khối catch đơn, tính năng này đơn giản mã.

Dưới đây là cú pháp cơ bản:

catch (IOException|FileNotFoundException ex) {

logger.log(ex);

throw ex;

Xử lý ngoại lệ bằng từ khóa Throws/Throw trong Java

Nếu một phương thức không xử lý ngoại lệ checked exception, phương thức đó phải khai báo nó bằng cách sử dụng từ khóa throws. Từ khóa throws nằm cuối chữ ký của phương thức.

Bạn có thể ném ngoại lệ hoặc tạo một ngoại lệ mới hoặc ngoại lệ mà bạn vừa bắt bằng cách sử dụng từ khóa throw.

Giữa từ khóa throws và từ khóa throw có sự khác nhau. Throws được sử dụng để trì hoãn xử lý ngoại lệ checked exception còn throw được sử dụng để gọi ngoại lệ.

Ví dụ phương thức dưới đây khai báo throws RemoteException:

ngoai le va xu ly ngoai le trong java 8

Một phương thức có thể khai báo throws ngoại lệ nhiều hơn, trong trường hợp các ngoại lệ được khai báo trong một danh sách được ngăn cách nhau bởi dấu phẩy.

Ví dụ phương thức dưới đây khai báo throws RemoteException và InsufficientFundsException:

ngoai le va xu ly ngoai le trong java 9

Khối Finally

Khối finally theo sau một khối try hoặc một khối catch. Khối finally được thực thi, kể cả trong trường hợp nếu xuất hiện ngoại lệ.

Sử dụng khối finally cho phép bạn chạy các lệnh kiểu cleanup, bất kể điều gì sẽ xảy ra trong mã được bảo vệ.

Khối finally nằm ở cuối khối catch.

Cú pháp:

try {

// Protected code

} catch (ExceptionType1 e1) {

// Catch block

} catch (ExceptionType2 e2) {

// Catch block

} catch (ExceptionType3 e3) {

// Catch block

}finally {

// The finally block always executes.

}

Ví dụ:

ngoai le va xu ly ngoai le trong java 10

Trong ví dụ trên trả về kết quả đầu ra là:

Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3

First element value: 6

The finally statement is executed

Lưu ý:

- Mệnh đề catch không tồn tại nếu không có lệnh try.
- Không bắt buộc phải có mệnh đề finally ngay cả khi xuất hiện khối try / catch.
- Khối try không thể hiện diện nếu không có mệnh đề catch hoặc finally.
- Mã không thể xuất hiện giữa các khối try, catch và finally.

Lệnh try-with-resources trong Java

Khi sử dụng các tài nguyên như stream, connection, ... chúng ta phải đóng các tài nguyên này bằng cách sử dụng khối finally.

Trong ví dụ dưới đây, chương trình đọc dữ liệu từ 1 file bằng cách sử dụng FileReader và file này được đóng bằng cách sử dụng khối finally:

ngoai le va xu ly ngoai le trong java 11

try-with-resources còn gọi là automatic resource management (quản lý tài nguyên tự động), là cơ chế xử lý ngoại lệ mới được giới thiệu trên Java 7, tự động đóng các tài nguyên được sử dụng trong khối try catch.

Để sử dụng lệnh này, bạn chỉ cần khai báo các tài nguyên cần thiết trong dấu ngoặc, và tài nguyên được tạo sẽ tự động đóng sau khi khối kết thúc. Dưới đây là cú pháp lệnh try-with-resources:

Cú pháp:

try(FileReader fr = new FileReader("file path")) {

// use the resource

} catch () {

// body of catch

}

}

Ví dụ dưới đây là chương trình đọc dữ liệu trong 1 file sử dụng lệnh try-with-resources:

ngoai le va xu ly ngoai le trong java 12

Một số chú ý khi sử dụng lệnh try-with-resources:

- Để sử dụng lớp với lệnh try-with-resources, nó được thực hiện với AutoCloseable interface và phương thức close() được gọi tự động trong runtime.

- Bạn có thể khai báo nhiều lớp trong lệnh try-with-resources.
- Trong khi khai báo nhiều lớp trong khối try của lệnh try-with-resources, các lớp nàu được đóng theo thứ tự ngược lại.
- Ngoại trừ việc khai báo các tài nguyên trong dấu ngoặc đơn, mọi thứ đều giống trong khối try / catch của một khối try.
- Tài nguyên khai báo tại khối try được ngầm khai báo là cuối cùng.

Tạo lớp User-defined Exception trong Java

Bạn có thể tự tạo các ngoại lệ trong Java. Tuy nhiên cần lưu ý một số điểm dưới đây khi viết một lớp ngoại lệ trong Java:

- Tất cả các ngoại lệ phải là con của Throwable.
- Nếu muốn viết ngoại lệ checked exception, tự động được xử lý bởi Handle hoặc Declare Rule, bạn cần phải mở rộng lớp Exception.
- Nếu muốn viết ngoại lệ runtime exception, bạn cần phải rộng lớp RuntimeException.

Để định nghĩa lớp ngoại lệ, bạn sử dụng cú pháp dưới đây:

class MyException extends Exception {

}

Chỉ cần mở rộng lớp ngoại lệ được xác định trước để tạo một ngoại lệ riêng. Các ngoại lệ này được xem là ngoại lệ checked exception. Lớp InsufficientFundsException dưới đây là một ngoại lệ user-defined exception, mở rộng lớp Exception.

Lớp ngoại lệ cũng giống như các lớp khác, có chứa các trường và phương thức hữu ích.

Ví dụ:

ngoai le va xu ly ngoai le trong java 13

Để biểu diễn sử dụng ngoại lệ user-defined exception, lớp CheckingAccount dưới đây chứa phương thức withdraw (), ném một ngoại lệ nsufficientFundsException:

ngoai le va xu ly ngoai le trong java 14

Chương trình BankDemo dưới đây biểu biểu diễn phương thức deposit () và withdraw () của CheckingAccount:

ngoai le va xu ly ngoai le trong java 15

Biên dịch tất cả 3 file trên và chạy BankDemo sẽ trả về kết quả đầu ra là:

Depositing $500...

Withdrawing $100...

Withdrawing $600...

Sorry, but you are short $200.0

InsufficientFundsException

at CheckingAccount.withdraw(CheckingAccount.java:25)

at BankDemo.main(BankDemo.java:13)

Các ngoại lệ phổ biến

Trong Java có 2 ngoại lệ phổ biến của Exception và Error:

- JVM Exception: Đây là các ngoại lệ / lỗi được JVM đưa ra độc quyền. Ví dụ: NullPointerException, ArrayIndexOutOfBoundsException, ClassCastException.

- Programmatic Exception: Những ngoại lệ này được ứng dụng hoặc API lập trình rõ ràng. Ví dụ: IllegalArgumentException, IllegalStateException.

http://thuthuat.taimienphi.vn/ngoai-le-va-xu-ly-ngoai-le-trong-java-32576n.aspx
Như vậy trong bài viết trên Zaidap.com vừa giới thiệu cho bạn và ngoại lệ và xử lý ngoại lệ trong Java, bạn đọc hảy tìm hiểu thêm hướng dẫn cơ bản về ngôn ngữ Java để nắm các cách xử lý linh hoạt trong ngôn ngữ này. Nếu có thắc mắc nào cần giải đáp, bạn vui lòng để lại ý kiến của mình trong phần bình luận bên dưới bài viết nhé.

0