2008-10-26 19 views

Trả lời

25

Tôi nghĩ rằng bạn cần phải tự hỏi một câu hỏi khác nhau slighly "Lợi thế gì tạo ra một mới ngoại lệ cho tôi hoặc nhà phát triển sử dụng mã của tôi? " Thực sự là lợi thế duy nhất nó mang lại cho bạn hoặc những người khác là khả năng xử lý ngoại lệ. Điều đó có vẻ như một câu trả lời rõ ràng nhưng thực sự nó không phải. Bạn chỉ nên xử lý các ngoại lệ mà bạn có thể phục hồi hợp lý từ đó. Nếu ngoại lệ bạn ném là một lỗi thực sự gây tử vong, tại sao các nhà phát triển có cơ hội xử lý sai?

khác ở cuộc thảo luận sâu: Custom exceptions: When should you create them?

+3

Đồng thời tạo một tài khoản nếu bạn không muốn gây nhầm lẫn cho người dùng .. java.lang.Exception có thể có nghĩa là một tỷ những điều có thể đã đi sai .. được cụ thể với ví dụ AppFileNotFound (sFilePath) - giúp cắt giảm xung quanh các bụi cây ... – Gishu

7

Khi tôi muốn đối xử với ngoại lệ của tôi khác với tất cả mọi người khác. Nếu tôi muốn bắt và tuyên truyền mọi người khác, hoặc nếu tôi muốn bắt người khác và tuyên truyền của tôi, hoặc nếu tôi muốn bắt cả hai nhưng đối xử với họ khác, thì tôi sẽ định nghĩa một lớp riêng biệt cho các ngoại lệ của tôi. Nếu tôi muốn đối xử với họ tất cả như nhau, hoặc bằng cách tuyên truyền cả hai hoặc bằng cách bắt cả hai (và làm điều tương tự một trong hai cách với các trường hợp ngoại lệ bị bắt), tôi sẽ sử dụng lớp tiêu chuẩn.

-1

Trong hầu hết các trường hợp, bạn không nên tạo lớp ngoại lệ của riêng mình.

Có một xu hướng trong các lập trình viên mới làm quen để tạo ra lớp ngoại lệ riêng của họ chỉ để họ có thể sử dụng một tên chỉ dẫn hơn về loại lỗi. Vì vậy, bạn sẽ tìm thấy các lớp như FTPInitializationException, DAOFactoryException, vv mặc dù các ngoại lệ như vậy không được xử lý khác với các ngoại lệ tiêu chuẩn. Đây rõ ràng là một mô hình chống nên tránh.

+0

Tư vấn rằng các lập trình viên ném một java.lang.Exception là tồi tệ hơn nhiều so với việc ném lớp riêng của chúng hơn là mở rộng java.lang.Exception; có nhiều ngoại lệ mở rộng j.l.Exception không nên bị bắt. – janm

+0

Được giảm giá. Mọi người có thể trực tiếp ném "RuntimeException" mà không có phân lớp phụ, vì người gọi không được mong đợi có thể khôi phục. Nhưng khi bạn ném "Ngoại lệ", bạn mong đợi người gọi có thể phục hồi. Nhưng nếu bạn không cung cấp cho họ một lớp con cụ thể, làm thế nào họ có đủ ngữ cảnh để phục hồi? – benjismith

2

Bắt đầu luôn bằng cách sử dụng các lớp ngoại lệ chung và sau đó khi có nhu cầu xử lý đặc biệt, hãy thay đổi nó.

  1. Khi tạo phương thức lần đầu tiên, chỉ cần cho phép ngoại lệ đi qua.

  2. Nếu có trường hợp ngoại lệ phải được xử lý, những trường hợp đó có thể chỉ được xác định trong lần ném hoặc được bao bọc cho một số ngoại lệ thời gian chạy hoặc được bao gồm ngoại lệ ném riêng. Tôi thích ngoại lệ thời gian chạy trong nhiều trường hợp. Xác định định nghĩa ném nên tránh cho đến khi có nhu cầu cho nó từ quan điểm API.

  3. Sau đó khi có nhu cầu xử lý cụ thể cho một ngoại lệ trong một số người gọi, hãy quay lại và tạo ngoại lệ mới cho nó.

Vấn đề là tránh làm thêm việc trước khi biết điều gì là cần thiết.

+1

Lớp Ngoại lệ là đặc biệt; "catch (Exception e)" sẽ bắt tất cả mọi thứ mà bạn có lẽ không nên đánh bắt. – janm

+0

Tôi không nói bắt nó. "Các lớp ngoại lệ phổ biến" có thể có nghĩa là ngoại lệ chung của riêng bạn. Vấn đề là để tránh tạo ra các lớp học cụ thể trước khi có nhu cầu cho họ. – iny

+0

Tôi nghĩ rằng nó là giá trị làm cho rõ ràng trong câu trả lời của bạn; "lớp ngoại lệ chung" duy nhất trong câu hỏi là java.lang.Exception; sử dụng đó là xấu. Nếu bạn có "ném ngoại lệ" trong spec ngoại lệ của bạn thì người gọi buộc phải đối phó với mọi thứ. – janm

6

NẾU có ngoại lệ hiện tại với thời gian chạy ngôn ngữ hoặc thư viện, hãy sử dụng nó ELSE tạo tài liệu của riêng bạn, viết tài liệu tốt và sẽ hoạt động trong 99% các trường hợp.

11

Lý do một:

Cần nắm bắt nội dung cụ thể. Nếu mã gọi cần xử lý một điều kiện đặc biệt cụ thể, bạn cần phân biệt Ngoại lệ của mình và Java phân biệt các ngoại lệ với các loại khác nhau, vì vậy bạn cần phải viết riêng của mình.

Về cơ bản, nếu ai đó đã viết:

catch(ExistingException e) { 
    if({condition}) { 
    { some stuff here} 
    } 
    else { 
    { different stuff here} 
    } 
} 

Có thể bạn muốn viết một phần mở rộng cụ thể; bắt Kết hợp ngoại lệ rõ ràng hơn so với điều kiện, IMHO.

Hãy nhớ rằng: ngoại lệ mới của bạn có thể một lớp con của RuntimeException

Lý do hai:

API củng cố. Nếu bạn viết một giao diện và bạn có nhiều triển khai, có thể là họ sẽ gọi các API khác nhau với một bó toàn bộ phi RuntimeExceptions khác nhau ném:

interface MyInterface { 
    void methodA(); 
} 

class MyImplA { 
    void methodA() throws SQLException { ... } 
} 

class MyImplB { 
    void methodA() throws IOException { ... } 
} 

Bạn có thực sự muốn MyInterface.methodA để ném SQLException và IOException? Có lẽ sau đó nó có ý nghĩa để bọc các trường hợp ngoại lệ có thể trong một ngoại lệ tùy chỉnh. Mà một lần nữa có thể là một RuntimeException. Hoặc ngay cả chính RuntimeException ...

0

Tôi sẽ sử dụng ngoại lệ từ API Java khi ngoại lệ liên quan đến API. Nhưng nếu một tình huống đặc biệt phát sinh đó là duy nhất cho API của riêng tôi thì tôi sẽ tạo ra một ngoại lệ cho nó. Ví dụ nếu tôi có một đối tượng Range với hai thuộc tính min và max và min bất biến < = max thì tôi sẽ tạo ra một ngoại lệ InvalidRangeException.

Khi tôi viết mã, điều này sẽ giúp bởi vì tôi biết nếu ngoại lệ bắt nguồn bởi vì tôi đã vi phạm một trong các điều kiện của riêng tôi hoặc điều gì đó của nó từ API Java.

8

Tôi tin rằng:

catch (Exception e) { 
    ... 
} 

... là một antipattern rằng cần phải tránh. Bạn có thể muốn một trung tâm rộng bắt một nơi nào đó trong ứng dụng của bạn, để đăng nhập một lỗi và ngăn chặn toàn bộ ứng dụng từ chấm dứt - nhưng có họ rải rác xung quanh willy-nilly là xấu.

Tại sao:

try { 
    if(myShape.isHidden()) { 
     throw new Exception(); 
    } 
    // More logic 
} catch (Exception e) { 
    MyApp.notify("Can't munge a hidden shape"); 
} 

Vì vậy, bạn cố gắng này, và do một lỗi mã hóa, myShape là null. Một NullPointerException được ném khi thời gian chạy cố gắng để vô hiệu hóa myShape. Mã này báo cáo một hình dạng ẩn, khi nó cần được báo cáo một con trỏ null.

Hoặc tạo ngoại lệ của riêng bạn hoặc tìm một ngoại lệ phù hợp chuyên biệt trong API. Nó không phải là nếu mở rộng ngoại lệ hoặc RuntimeException là hợp lý.

+0

Bạn có thể làm 'ném ngoại lệ mới (" Không thể lén hình dạng ẩn "); ... MyApp.notify (e.getMessage()) '. Đó là dễ đọc hơn và dễ quản lý hơn. – brice

+0

Điều đó tốt nếu tất cả những gì bạn muốn làm là báo cáo một chuỗi. Điều gì sẽ xảy ra nếu nó là 'catch (Exception e) {unHideShape (myShape); } '? – slim

+0

Tôi chắc chắn rằng tôi có ý nghĩa gì đó cụ thể bởi nhận xét đó ba năm trước, nhưng tôi không biết gì :) Tôi đồng ý với tình cảm của bạn. +1 – brice

1

Tôi không thể tưởng tượng cụ thể việc ném một java.lang.Exception nếu một số đối tượng/lớp/phương pháp gặp sự cố. Nó quá chung chung - nếu bạn không định tạo lớp Ngoại lệ của riêng mình, có vẻ như tôi phải có ít nhất một loại ngoại lệ cụ thể hơn trong API.

4

Phần mềm nắm bắt ý nghĩa.

Có hầu như không có lý do gì để ném ngoại lệ hiện tại: JVM đã thực hiện điều đó cho bạn. Phiên bản ngoại lệ của bạn không thực sự chính xác và việc ném "Ngoại lệ" cũng không có ý nghĩa.

Bạn có thể có DataFormatException vì thuật toán phân tích cú pháp bạn đã viết. Điều này, tuy nhiên, là rất hiếm.

Khi chương trình của bạn gặp phải tình huống đặc biệt, chương trình của bạn hầu như luôn duy nhất đối với chương trình của bạn. Tại sao buộc phải phù hợp với tình huống ngoại lệ của bạn vào một ngoại lệ hiện có? Nếu nó là duy nhất cho chương trình của bạn, thì ... tốt ... nó là duy nhất. Đặt tên theo cách đó.

Tuy nhiên, không cung cấp một lớp ngoại lệ duy nhất cho mỗi thư duy nhất. Một ngoại lệ lớp có thể có nhiều thông báo biến thể và chi tiết hỗ trợ.

Quy tắc ngón tay cái của Python, được dịch sang Java, là xác định bất kỳ ngoại lệ duy nhất nào ở cấp gói. [Trong Python, họ đề xuất các ngoại lệ ở cấp độ "mô-đun", một thứ không chính xác dịch sang Java.]

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