2012-02-21 39 views
21

Tôi là nhà phát triển C# thỉnh thoảng thực hiện mã hóa bằng Java. Ai đó có thể giải thích một cách đơn giản những gì được kiểm tra ngoại lệ trong Java và tại sao nó cần thiết? Đã không đi qua thuật ngữ này trong C#.Ngoại lệ được kiểm tra trong Java/C# là gì?

+1

Ý của bạn là "ngoại lệ đã kiểm tra"? Vui lòng chỉnh sửa câu hỏi nếu bạn đã làm. – dasblinkenlight

+1

@dasblinkenlight, nó đã được gắn thẻ ngoại lệ, vì vậy tôi đã chỉnh sửa nó. –

+0

cảm ơn! xin lỗi về lỗi đánh máy đó. – blitzkriegz

Trả lời

43

Trường hợp ngoại lệ được kiểm tra là ngoại lệ mà trình biên dịch yêu cầu bạn xử lý theo một cách nào đó.

Trong Java, ngoại lệ được kiểm tra là Throwable s không phải là RuntimeException, Error hoặc một trong các lớp con của chúng.

Các nhà thiết kế Java cảm thấy cần thiết để đảm bảo các chương trình xử lý các ngoại lệ có khả năng hợp lý. Ví dụ cổ điển là IOException. Bất cứ lúc nào một chương trình làm I/O, có khả năng thất bại. Đĩa có thể đầy, tệp có thể không tồn tại, có thể có sự cố về quyền, v.v.

Vì vậy, Java được thiết kế sao cho chương trình phải xử lý cú pháp ngoại lệ theo một cách nào đó. Điều này có thể là với một khối catch, hoặc bằng cách rethrowing ngoại lệ trong một số cách.

C# không có ngoại lệ đã kiểm tra. Họ quyết định để lại vấn đề này cho các nhà phát triển ứng dụng (interview). Các trường hợp ngoại lệ được kiểm tra là gây tranh cãi bởi vì chúng có thể làm cho tiết đoạn mã, trong khi các nhà phát triển đôi khi xử lý chúng một cách trivially với các khối catch rỗng. Hơn nữa, nó có thể là tùy ý mà các phương thức thư viện chuẩn ném các ngoại lệ đã kiểm tra. Ví dụ: tại sao không File.delete (API Java 7 mới thực hiện điều này theo cách khác) ném IOException?

Một mối quan tâm khác mà Hejlsberg lưu ý trong cuộc phỏng vấn đó là khả năng phiên bản. Việc thêm một ngoại lệ đã kiểm tra vào một mệnh đề throw sẽ buộc tất cả mã sử dụng phương thức đó phải được sửa đổi và biên dịch lại.

+1

giải thích tuyệt vời. cảm ơn! – blitzkriegz

+4

'Thêm một ngoại lệ đã kiểm tra vào một mệnh đề ném buộc tất cả các mã sử dụng phương thức đó sẽ được sửa đổi và biên dịch lại' - vì vậy bạn có các ngoại lệ không được kiểm tra. Vâng, ngoại trừ nếu bạn nghĩ rằng 'Sẽ thất bại trong một số trường hợp' là cách bạn muốn mô tả API của bạn. MỌI ngoại lệ là một phần của giao diện công cộng của một phương thức, thêm vào sau là giống như nói "Oh và từ bây giờ trên tham số int đó sẽ có ý nghĩa ngữ nghĩa hoàn toàn khác - nhưng đừng lo, nó vẫn tương thích nhị phân!" – Voo

+2

@Voo, điều này được thảo luận cụ thể trong [phần này] (http://www.artima.com/intv/handcuffs2.html) của cuộc phỏng vấn. Hejlsberg lập luận rằng không phải mọi ngoại lệ đều cần được xử lý bằng mã gọi ngay lập tức. Ông nói rằng một số được xử lý tốt nhất bởi trình xử lý tin nhắn chính, ngay cả khi trình xử lý chính đó không được viết với kiến ​​thức cụ thể về ngoại lệ mới. –

0

Trường hợp ngoại lệ được kiểm tra là các ngoại lệ yêu cầu bất kỳ lớp "tiêu thụ" nào phải mã để kiểm tra rõ ràng (và hy vọng xử lý) ngoại lệ. Ví dụ, nếu lớp Apple có phương thức Eat() bao gồm ngoại lệ đã kiểm tra của WormFound thì bất kỳ mã nào gọi phương thức đó sẽ cần phải nắm bắt rõ ràng ngoại lệ đó.

Một lưu ý phụ là tính năng của Java chứ không phải của C#.

(Tại thời điểm khi C# đã được tạo ra, những ưu ngoại lệ kiểm tra là không quá rõ ràng trong mắt của đội C# vì vậy họ không được bao gồm.)

6

Trong Java, một kiểm tra ngoại lệ (như Matthew Flaschen chỉ ra một cách chính xác) là một ngoại lệ mà trình biên dịch yêu cầu bạn phải xử lý. Đây là những trường hợp ngoại lệ được công bố trên các định nghĩa hàm (ví dụ function bob() throws ImNotBobException { ... } để nói rằng gọi hàm có thể ném rằng ngoại lệ -. Ví dụ NumberFormatException khi phân tích một số nguyên, hoặc IOException khi viết vào một tập tin

Tuy nhiên, một số trường hợp ngoại lệ có thể được ném từ các vị trí không xác định hoặc không mong muốn đơn giản là không thực tế để xử lý trên mọi cấp độ, do đó trình biên dịch không yêu cầu bạn xử lý các trường hợp này. để gọi một phương thức trên một đối tượng khi đối tượng đó chưa được khởi tạo, nghĩa là null - điều này sẽ dẫn đến một NullPointerException.)

Hy vọng điều này sẽ hữu ích.

+0

ngoại lệ đã kiểm tra là lỗi. Bất kỳ lời giải thích nào khác đều sai. – earizon

-2

(một vài năm sau đó, cho người đến đây thông qua các hãng hàng không của Google)

Checked-trường hợp ngoại lệ là một sai lầm trong thiết kế của ngôn ngữ Java. GIAI ĐOẠN. Bất cứ khi nào bạn tìm thấy một trường hợp ngoại lệ được kiểm tra, hãy bọc chúng trong một ngoại lệ không được kiểm soát (có thể là một RuntimeException).

Thật không may, do các vấn đề tiếp thị, Sun đầu tiên, sau đó Oracle đã không thể công khai nhận ra sai lầm của họ.

Vào thời điểm Java được tạo, việc xử lý ngoại lệ không rõ ràng. Các nhà thiết kế Java ngây thơ nghĩ rằng buộc các nhà phát triển kiểm tra các ngoại lệ trong thời gian biên dịch là một ý tưởng hay. Mặc dù điều này có vẻ trực quan, nhưng điều này đã trở thành một dạng chống mẫu, tương tự như việc sử dụng "GOTO". Nó không bao giờ làm việc trong thực tế và gây ra rất nhiều vấn đề. Các ngoại lệ phải được xử lý trong một "vòng lặp chính" hoặc "bộ điều khiển", vì nếu không, chúng có thể được xử lý bên trong hàm nâng lỗi, chúng sẽ không là ngoại lệ, nhưng một lỗi dự tính phải được hỗ trợ bởi giá trị trả về API bình thường. Một ngoại lệ, bởi bản chất riêng của nó, là một cái gì đó không được dự tính và điều đó không cho phép thực thi luồng thông thường.

Lưu ý ví dụ rằng Spring, khung Java "chuẩn" cho phát triển ứng dụng doanh nghiệp, chỉ giới hạn để bao bọc các ngoại lệ đã kiểm tra thành các ngoại lệ không được kiểm soát.

C# đã khắc phục sự cố này. Trong thực tế, C# không có vấn đề này.

Các vấn đề liên quan