Java: Dùng throw để ném ngoại lệ
Trước khi bạn có thể bắt một ngoại lệ thì phải có một nơi nào đó ngoại lệ được ném ra. Bất kỳ mã lệnh nào đều có thể ném một ngoại lệ: mã của bạn, mã từ một gói phần mềm được viết bởi một người nào khác chẳng hạn như các gói đi kèm với các nền tảng Java, hoặc môi trường thời gian chạy Java. Bất kể ngoại lệ được ném là gì, nó luôn luôn được ném bằng câu lệnh throw.
Như bạn có thể nhận thấy, nền tảng Java cung cấp nhiều lớp ngoại lệ. Tất cả các lớp này đều là con cháu của lớp Throwable
, và tất cả các chương trình cho phép để phân biệt giữa các loại khác nhau của các ngoại lệ có thể xảy ra trong quá trình thực hiện chương trình.
Bạn cũng có thể tạo các lớp ngoại lệ của riêng bạn để đại diện cho các vấn đề có thể xảy ra trong lớp bạn viết. Trong thực tế, nếu bạn là một nhà phát triển gói phần mềm, bạn có thể phải tạo ra tập các lớp ngoại lệ của riêng bạn để cho phép người sử dụng phân biệt giữa lỗi có thể xảy ra trong gói của bạn với lỗi xảy ra trong nền tảng Java hoặc các gói khác.
Bạn cũng có thể tạo các ngoại lệ kết chuỗi, xin xem thêm tại bài viết Ngoại lệ kết chuỗi.
Câu lệnh throw
Tất cả các phương thức đều sử dụng câu lệnh throw
để ném ra ngoại lệ. Câu lệnh throw
yêu cầu một tham số duy nhất: một đối tượng Throwable. Đối tượng Throwable là thể hiện của bất kỳ lớp con nào của lớp Throwable
. Dưới đây là một ví dụ về câu lệnh throw
.
throw someThrowableObject;
Sau đây là phương thức pop
được lấy từ một lớp dùng để thực hiện một đối tượng ngăn xếp chung. Phương thức sẽ loại bỏ các thành phần đầu khỏi stack và trả về đối tượng.
public Object pop() {
Object obj;
if (size == 0) {
throw new EmptyStackException();
}
obj = objectAt(size - 1);
setObjectAt(size - 1, null);
size--;
return obj;
}
Phương thức pop
kiểm tra để xem liệu có phần tử nào đang ở trên stack hay không. Nếu stack rỗng (kích thước của nó là bằng 0
), thì pop
sẽ khởi tạo một đối tượng EmptyStackException
(một thành viên của java.util
) và ném nó. Bài viết Tạo lớp ngoại lệ sẽ giải thích cách tạo ra các lớp ngoại lệ của riêng bạn. Bây giờ, điều bạn cần ghi nhớ là bạn chỉ có thể ném các đối tượng kế thừa từ lớp java.lang.Throwable
.
Lưu ý rằng việc khai báo phương thức pop
không được chứa mệnh đề throws
. EmptyStackException
không phải là một ngoại lệ checked, vì vậy pop
không cần phải quan tâm đến điều này.
Lớp Throwable và các lớp con
Các đối tượng kế thừa từ lớp Throwable
bao gồm các lớp con trực tiếp và gián tiếp. Hình dưới đây minh họa mô hình phân cấp lớp của lớp Throwable
và các lớp con quan trọng nhất của nó. Như bạn có thể thấy, Throwable
có hai lớp con trực tiếp là Error
và Exception
.
Lớp Throwable.
Lớp Error
Khi xảy ra thất bại đối với liên kết động hoặc lỗi ổ đĩa cứng trong máy ảo Java (JVM) chẳng hạn, thì JVM sẽ ném ra một lỗi Error
. Các chương trình đơn giản thường không bắt hoặc ném các lỗi Error
.
Lớp Exception
Hầu hết các chương trình ném và bắt các đối tượng có nguồn gốc từ lớp Exception
. Exception
sẽ cho ta biết rằng có một vấn đề gì đó đã xảy ra, nhưng nó không phải là một vấn đề hệ thống nghiêm trọng. Hầu hết các chương trình bạn viết sẽ ném và bắt các Exception
.
Các nền tảng Java định nghĩa nhiều con cháu của lớp Exception
. Những con cháu này cho biết các loại ngoại lệ khác nhau có thể xảy ra. Ví dụ, IllegalAccessException
báo hiệu rằng một phương thức đặc biệt không thể được tìm thấy, và NegativeArraySizeException
chỉ ra rằng một chương trình đạng cố gắng để tạo ra một mảng với kích thước âm (nhỏ hơn 0).
Một lớp con nữa của Exception
là RuntimeException
, nó được dành riêng cho ngoại lệ chỉ ra việc sử dụng không đúng một API nào đó. Một ví dụ là NullPointerException
, ngoại lệ này xảy ra khi một phương thức cố gắng truy cập vào một thành viên của một đối tượng thông qua một tham chiếu null
. Bài viết Ngoại lệ unchecked - Tranh luận sẽ cho ta biết lý do tại sao hầu hết các ứng dụng không nên ném ngoại lệ runtime hoặc lớp con của RuntimeException
.