Các phương thức ném RuntimeException có nên chỉ ra nó trong chữ ký phương thức không?


86

Ví dụ: nhiều phương thức trong framework / JDK có thể ném

java.lang.SecurityException 

nhưng điều này không được chỉ ra trong chữ ký của phương pháp (vì đó là một thông lệ thường dành cho các trường hợp ngoại lệ đã kiểm tra). Tôi muốn tranh luận rằng việc khai báo RuntimeExceptions trong method sigs có nhiều lợi ích (giống như kiểm tra kiểu tĩnh chẳng hạn). Tôi say rượu hay sao?

Câu trả lời:


70

Tôi sẽ không khai báo một ngoại lệ không được kiểm tra trong chữ ký, vì nó gây hiểu lầm cho người dùng API đó. Không còn rõ ràng liệu ngoại lệ có được xử lý rõ ràng hay không.

Khai báo nó trong javadoc là một cách tiếp cận tốt hơn vì nó cho phép ai đó xử lý nó nếu họ nghĩ nó cần thiết, nhưng biết rằng họ có thể bỏ qua nó nếu họ muốn. Điều này làm cho sự tách biệt giữa được chọn và không được chọn rõ ràng.


4
Trình biên dịch java không buộc bạn phải xử lý RuntimeExceptions đã khai báo. Vì vậy, bạn có thể khai báo chúng, với mục đích như một "gợi ý" cho các nhà phát triển. Nó có thể thảo luận, nếu JavaDoc là một nơi tốt hơn cho điều đó. Điểm quan trọng về các Ngoại lệ được chọn và không được chọn. Đã kiểm tra và không kiểm tra Ngoại lệ là, Java thực sự có ý nghĩa như thế nào với (Thời gian biên dịch-) Ngoại lệ (đã kiểm tra) và RuntimeExceptions (bỏ chọn).
Guardian667,

5
Trong Spring, việc khai báo các ngoại lệ không được kiểm tra trong chữ ký phương thức bắt đầu trở thành một thông lệ phổ biến.
nascar

38

Từ hướng dẫn Java của Oracle :

"Nếu việc ghi lại API của một phương thức là rất tốt, bao gồm các ngoại lệ mà nó có thể ném ra, tại sao không chỉ định các ngoại lệ thời gian chạy?" Các ngoại lệ thời gian chạy đại diện cho các vấn đề là kết quả của sự cố lập trình và do đó, mã ứng dụng API không thể được mong đợi một cách hợp lý để khôi phục chúng hoặc xử lý chúng theo bất kỳ cách nào. Những vấn đề như vậy bao gồm các ngoại lệ số học, chẳng hạn như chia cho số không; ngoại lệ con trỏ, chẳng hạn như cố gắng truy cập một đối tượng thông qua một tham chiếu rỗng; và lập chỉ mục các ngoại lệ, chẳng hạn như cố gắng truy cập vào một phần tử mảng thông qua một chỉ mục quá lớn hoặc quá nhỏ.

Các ngoại lệ thời gian chạy có thể xảy ra ở bất cứ đâu trong một chương trình và trong một chương trình điển hình, chúng có thể rất nhiều. Việc phải thêm ngoại lệ thời gian chạy trong mọi khai báo phương thức sẽ làm giảm độ rõ ràng của chương trình.


Do đó, trình biên dịch không yêu cầu bạn bắt hoặc chỉ định các ngoại lệ thời gian chạy (mặc dù bạn có thể).
nascar

18

Hãy xem javadoc cho Bộ sưu tập # add

Có rất nhiều trường hợp ngoại lệ chưa được kiểm tra được đề cập:

Throws:
UnsupportedOperationException - add is not supported by this collection.
ClassCastException - class of the specified element prevents it from being added to this collection.
NullPointerException - if the specified element is null and this collection does not support null elements.
IllegalArgumentException - some aspect of this element prevents it from being added to this collection.

Nếu bạn đủ kiên nhẫn, tôi khuyên bạn nên ghi lại kỹ lưỡng các trường hợp ngoại lệ có thể xảy ra bởi các phương pháp của bạn theo cách này. Theo một cách nào đó, việc làm này thậm chí còn quan trọng hơn đối với các trường hợp ngoại lệ chưa được kiểm tra, vì các trường hợp ngoại lệ đã được kiểm tra có phần tự ghi lại (trình biên dịch buộc mã gọi phải xác nhận chúng).


6
Câu trả lời này là sai. Bạn đang nói về các câu lệnh Javadoc trong khi câu hỏi về throwschữ ký phương thức. Đây không phải là những điều giống nhau. Có, bạn hoàn toàn nên ghi lại tất cả các ngoại lệ do API của bạn đưa ra, nhưng câu hỏi không phải về điều đó.
Gili,

8

Theo quan điểm của tôi, tốt hơn nên khai báo các ngoại lệ thời gian chạy ít nhất là trong javadoc cho phương thức. Khai báo nó trong chữ ký càng làm cho nó rõ ràng hơn những gì có thể xảy ra khi có sự cố. Đây là lý do chính của tôi để đề nghị cung cấp thông tin này.

FYI: theo thời gian đã trôi qua (bây giờ là năm 2017), giờ đây tôi đang nghiêng nhiều hơn về việc chỉ ghi lại chúng trong javadoc và tránh các ngoại lệ đã kiểm tra càng nhiều càng tốt.


3

Theo quan điểm của tôi, các ngoại lệ không được kiểm tra không bao giờ được khai báo trong chữ ký phương thức vì điều đó trái với bản chất của chúng.

Tuy nhiên, nếu một phương thức có khả năng ném ra một số ngoại lệ không được kiểm tra, lưu ý rằng các trường hợp có thể xảy ra trong @throws trong Javadoc có thể hữu ích cho những người khác gọi phương thức để hiểu những gì có thể xảy ra sai. Tuy nhiên, điều này chỉ hữu ích đối với các trường hợp ngoại lệ mà người gọi có thể xử lý được (chẳng hạn như NPE do đầu vào không tốt, v.v.)


3

Nếu bạn đang viết một api để người khác sử dụng, thì có rất nhiều lý do để đưa ra tài liệu rõ ràng về ý định của bạn trong api và không có nhược điểm nào khi khai báo RuntimeExceptions trong chữ ký phương thức.


1

Điều này liên quan đến cuộc thảo luận về các trường hợp ngoại lệ đã kiểm tra . Hầu hết sẽ đồng ý rằng các ngoại lệ không nên được khai báo trong các chữ ký phương thức.

Cũng có một cuộc thảo luận liên quan đến cách sử dụng các ngoại lệ thời gian chạy. Tôi đồng ý với một người đăng rằng các ngoại lệ thời gian chạy phải biểu thị một lỗi lập trình hoặc một điều kiện nghiêm trọng. Vì vậy, không có nhiều lợi ích khi tuyên bố chúng trong chữ ký. Mọi phương pháp đều có thể thông qua một.


Trường hợp ngoại lệ phân tích cú pháp hoặc một số ngoại lệ loại xác thực dữ liệu khác phù hợp với khi đó. Bạn đang ngụ ý rằng bạn không nên sử dụng các ngoại lệ đã kiểm tra nhưng sau đó hạn chế những ngoại lệ không được kiểm tra có nghĩa là được sử dụng cho.
Robin

1
Những gì tôi đang nói là nhà phát triển không nên bị buộc phải bắt các ngoại lệ đã kiểm tra. Vì vậy không cần khai báo chúng trong method signature. Trong Java, bạn có thể biến đổi chúng trong các ngoại lệ thời gian chạy, như Spring đang làm. Tôi cũng nói rằng các ngoại lệ thời gian chạy chỉ nên được ném vào các tình huống không thể khôi phục.
kgiannakakis
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.