Java: Ngoại lệ unchecked - Tranh luận
Do ngôn ngữ lập trình Java không yêu cầu các phương thức bắt hoặc xác định ngoại lệ unchecked (RuntimeException
, Error
, và các lớp con của chúng), nên lập trình viên có thể bị cám dỗ để viết code chỉ để ném ngoại lệ unchecked hoặc để làm cho tất cả các lớp ngoại lệ con của chúng kế thừa từ RuntimeException
. Các cách thức này đều cho phép các lập trình viên viết code mà không gây ra lỗi biên dịch và không làm ảnh hưởng đến việc xác định hoặc bắt bất kỳ ngoại lệ nào. Mặc dù điều này có vẻ thuận lợi cho các lập trình viên, nhưng nó lại bỏ qua yêu cầu bắt và xác định ngoại lệ và có thể gây ra vấn đề cho người khác sử dụng các lớp của bạn.
Tại sao các nhà thiết kế lại quyết định buộc một phương thức phải xác định tất cả các ngoại lệ checked đang không được bắt để có thể ném chúng vào trong phạm vi của chúng? Bất kỳ Exception
nào đều có thể được ném ra bởi một phương thức là một phần của giao diện lập trình public của phương thức. Do vậy khi gọi một phương thức thì cần phải biết về các ngoại lệ mà một phương thức có thể ném để chúng có thể quyết định cần làm gì đối với các ngoại lệ. Những ngoại lệ này là một phần của giao diện lập trình của phương thức tương tự các tham số và giá trị trả về của nó.
Câu hỏi tiếp theo có thể là: "Nếu nó đủ tốt để chỉ ra API của một phương thức trong đó các ngoại lệ có thể ném, thì tại sao lại không chỉ định ngoại lệ thời gian chạy?". Ngoại lệ runtime đại diện cho các vấn đề về kết quả của một vấn đề lập trình, và như vậy, mã lệnh trình khách API có thể không hợp lý để được dự kiến phục hồi từ chúng hoặc để xử lý chúng theo bất kỳ cách nào. Vấn đề này bao gồm cả các ngoại lệ số học, như là phép chia cho số 0; các ngoại lệ con trỏ, chẳng hạn như cố gắng để truy cập vào một đối tượng thông qua một tham chiếu null; và các ngoại lệ chỉ mục, chẳng hạn như cố gắng truy cập một phần tử mảng thông qua một chỉ số quá lớn hoặc quá nhỏ.
Các ngoại lệ runtime có thể xảy ra ở bất kỳ đâu trong một chương trình, thậm chí nó có thể có rất nhiều. Việc phải bổ sung thêm ngoại lệ thời gian chạy vào mỗi khai báo phương thức sẽ làm giảm đi tính rõ ràng của chương trình. Do đó, trình biên dịch không yêu cầu bạn phải bắt hoặc chỉ định ngoại lệ thời gian chạy (mặc dù bạn có thể).
Một trường hợp thực tế phổ biến để ném một ngoại lệ RuntimeException
là khi người dùng gọi một phương thức không chính xác. Ví dụ, một phương thức có thể kiểm tra nếu một trong các đối số của nó không phải là null
. Nếu một đối số là null
, thì phương pháp này có thể ném một NullPointerException
, đây là loại ngoại lệ unchecked.
Nói chung, không nên ném RuntimeException
hoặc tạo một lớp con của RuntimeException
đơn giản chỉ vì bạn không muốn bị làm phiền với việc chỉ định các ngoại lệ mà phương thức của bạn có thể ném.
Đây là hướng dẫn cuối cùng: Nếu trình khách có thể được dự kiến phục hồi từ một ngoại lệ, hãy tạo cho nó một ngoại lệ checked. Nếu trình khách không thể làm bất cứ điều gì để phục hồi từ ngoại lệ, hãy tạo cho nó một ngoại lệ unchecked.