Có một vài quy tắc xử lý ngoại lệ mà bạn nên ghi nhớ. Nhưng trước tiên, bạn cần nhớ rằng các ngoại lệ là một phần của giao diện được hiển thị bởi mã; tài liệu cho họ . Điều này đặc biệt quan trọng khi giao diện là một giao diện công cộng, tất nhiên, nhưng đó cũng là một ý tưởng rất tốt trong giao diện riêng tư.
Các ngoại lệ chỉ nên được xử lý tại điểm mà mã có thể làm điều gì đó hợp lý với chúng. Tùy chọn xử lý tồi tệ nhất là không làm gì cả về chúng, điều này chỉ nên được thực hiện khi đó chính xác là tùy chọn chính xác. (Khi tôi gặp tình huống như vậy trong mã của mình, tôi bao gồm một nhận xét về hiệu ứng đó để tôi biết không phải lo lắng về cơ thể trống rỗng.)
Tùy chọn tồi tệ thứ hai là ném một ngoại lệ không liên quan mà không có nguyên nhân kèm theo. Vấn đề ở đây là thông tin trong ngoại lệ ban đầu cho phép chẩn đoán vấn đề bị mất; bạn đang tạo ra thứ gì đó mà không ai có thể làm được gì (ngoài việc phàn nàn rằng, nó không hoạt động, và tất cả chúng ta đều biết chúng ta ghét những báo cáo lỗi đó như thế nào ).
Tốt hơn nhiều là đăng nhập ngoại lệ. Điều đó cho phép ai đó tìm ra vấn đề là gì và khắc phục nó, nhưng bạn chỉ nên đăng nhập ngoại lệ tại điểm mà nếu không nó sẽ bị mất hoặc được báo cáo qua kết nối bên ngoài. Đó không phải là vì đăng nhập thường xuyên là một vấn đề lớn như vậy, mà là vì đăng nhập quá nhiều có nghĩa là bạn chỉ cần nhật ký tiêu tốn nhiều dung lượng hơn mà không chứa nhiều thông tin hơn. Khi bạn đã đăng nhập ngoại lệ, bạn có thể báo cáo một PRECIS cho người dùng / khách hàng với một lương tâm tốt (miễn là bạn cũng bao gồm thời điểm phát sinh - hoặc nhận dạng mối tương quan khác - trong báo cáo đó để phiên bản ngắn có thể được xuất hiện lên với các chi tiết nếu cần thiết).
Tất nhiên, lựa chọn tốt nhất là xử lý hoàn toàn ngoại lệ, xử lý toàn bộ tình huống lỗi. Nếu bạn có thể làm điều này, bằng mọi cách hãy làm điều đó! Nó thậm chí có thể có nghĩa là bạn có thể tránh phải đăng nhập ngoại lệ.
Một cách để xử lý một ngoại lệ là đưa ra một ngoại lệ khác cung cấp mô tả vấn đề ở cấp độ cao hơn (ví dụ, failed to initialize
trong thời gian thay vì phạm lỗi index out of bounds
). Đây là một mô hình tốt miễn là bạn không bị mất thông tin về nguyên nhân của ngoại lệ; sử dụng ngoại lệ chi tiết để khởi tạo cause
ngoại lệ cấp cao hơn hoặc ghi nhật ký chi tiết (như đã thảo luận ở trên). Ghi nhật ký là thích hợp nhất khi bạn sắp vượt qua một ranh giới giữa các quá trình, như cuộc gọi IPC, bởi vì không có gì đảm bảo rằng lớp ngoại lệ cấp thấp sẽ xuất hiện ở đầu kia của kết nối. Giữ như một nguyên nhân kèm theo là thích hợp nhất khi vượt qua một ranh giới nội bộ.
Một mô hình khác mà bạn thấy là bắt và phát hành:
try {
// ...
} catch (FooException e) {
throw e;
}
Đây là một kiểu chống trừ khi bạn có các ràng buộc kiểu từ các catch
mệnh đề khác, điều đó có nghĩa là bạn không thể để ngoại lệ tự đi qua. Sau đó, nó chỉ là một tính năng xấu của Java.
Không có sự khác biệt thực sự giữa các ngoại lệ được kiểm tra và các ngoại lệ được kiểm tra ngoài thực tế là bạn phải khai báo các ngoại lệ được kiểm tra có ranh giới phương thức chéo. Vẫn là một ý tưởng tốt để ghi lại các trường hợp ngoại lệ không được kiểm tra (với @throws
nhận xét javadoc) nếu bạn biết rằng chúng bị ném một cách có chủ ý bởi mã của bạn. Đừng cố tình ném java.lang.Error
hoặc các lớp con của nó (trừ khi bạn đang viết một triển khai JVM).
Ý kiến: Một trường hợp lỗi không mong muốn luôn thể hiện lỗi trong mã của bạn. Các ngoại lệ được kiểm tra là một cách để quản lý mối đe dọa này và khi các nhà phát triển cố tình sử dụng các ngoại lệ không được kiểm tra như một cách để tránh rắc rối xử lý các trường hợp lỗi, bạn đang xây dựng nhiều khoản nợ kỹ thuật mà bạn sẽ phải dọn dẹp một thời gian nếu bạn muốn mã mạnh mẽ. Xử lý lỗi cẩu thả là không chuyên nghiệp (và nhìn vào xử lý lỗi là một cách tốt để xác định một lập trình viên thực sự giỏi như thế nào).