2011-07-28 33 views
6

Tôi muốn biết, có phải là good practice để đặt complete code bên trong một try block hoặc tôi nên đặt only the code which I feel it will cause a specific exception?
Và tôi nên bắt ngoại lệ cơ bản luônToàn bộ mã trong khối try/catch

Mã 1: mã hoàn chỉnh trong khối try

myFunction(){ 
try{ 
    ......... 
    Code with chance of OneException 
    ............. 
}catch(OneException e){ 
    ............ 
}catch(Exception e){ 
    .............. 
} 
} 

Mã 2: Chỉ có Bộ luật với cơ hội ngoại lệ trong khối try

myFunction(){ 
    ....... 
    try{ 
    Code with chance of OneException 
    }catch(OneException e){ 
    ............ 
    } 
    ............ 
} 

Mã số 3: Tôi có nên bắt ngoại lệ luôn

myFunction(){ 
     ....... 
     try{ 
     Code chance of OneException 
     }catch(OneException e){ 
     ............ 
     }catch(Exception e){ 
     .............. 
     } 
     ........ 
    } 

Trong số này (mã1, mã2 và mã3) cái nào là tốt nhất?
Tôi chủ yếu quan tâm đến mã hóa java và C++

+1

C không có ngoại lệ và không có ngôn ngữ được gọi là C/C++, vì vậy bạn nên xóa thẻ 'c'. –

+1

Các câu hỏi thực hành tốt nhất là không có chủ đề để xem xét mã số –

+0

Dường như giống như một câu hỏi về Stack Overflow hơn là Code Review. Tôi muốn bỏ phiếu để di chuyển, nhưng tôi không có đủ đại diện. –

Trả lời

5

Nói chung, bạn nên chỉ bắt ngoại lệ mà bạn quan tâm và bạn có thể xử lý. Đó là ... bắt một ngoại lệ, nơi bạn có thể làm điều gì đó s.t. người dùng không cảm nhận được sự cố hoặc khi cần thiết phải thông báo cho người dùng về sự cố.
Đối với tất cả các trường hợp ngoại lệ khác, hãy để chúng bật lên với tất cả các chi tiết của chúng (stacktrace, v.v.) mà bạn rõ ràng là đăng nhập. Lưu ý, rõ ràng điều này không có nghĩa là người dùng cũng sẽ thấy đầu ra ngoại lệ đó nhưng thay vào đó là lỗi chung.

Nói điều này, tôi giả định rằng khi bạn viết "Cơ hội mã của OneException", bạn biết cách xử lý OneException, nhưng không ngoại lệ, phải không? Vậy thì ... chỉ xử lý OneException.

3

Luôn nắm bắt chính xác những gì bạn có và không còn nữa. Bất kể chúng ta thử bao nhiêu, chúng ta không thể làm cho mã của chúng ta hoàn toàn "bằng chứng ngốc nghếch". Nếu ai đó vượt qua bạn một cái gì đó mà sẽ gây ra một số lỗi ngẫu nhiên, sau đó nó là công việc của họ để xử lý nó. Nếu mã của chúng tôi xử lý ngoại lệ của người khác có quá nhiều rủi ro bị tác dụng phụ không mong muốn.

Khi mã được đặt ở đâu: mã trước dòng có thể ném Ngoại lệ sẽ chạy theo cách, do đó, không thực sự có ý nghĩa khi đặt mã bên trong khối thử và trước mã . Mã sau khi ngoại lệ tiềm năng nên được đặt giữa try và catch nếu và chỉ nếu nó phụ thuộc vào mã tạo ra ngoại lệ. Vì vậy, nếu cuộc gọi kết nối cơ sở dữ liệu của bạn có thể thất bại, hãy đặt tất cả các truy vấn cơ sở dữ liệu bên trong khối thử.

Hạn chế "thời gian" dành để thử ... bắt giúp dễ đọc hơn và ít bị bắt tình cờ hơn. Tôi không thể nói cho bạn biết bao nhiêu giờ đã bị mất vì ai đó đã quyết định bắt một ngoại lệ cần được tuyên truyền.

+0

Tôi tin rằng có một ngoại lệ đối với mọi quy tắc. Cho phép nói rằng tôi cung cấp cho một số mã của tôi cho người khác, và trong mã đó tôi sẽ có một số thu thập số liệu thống kê.Sau đó, tôi muốn thống kê được gửi cho tôi, và tôi sẽ đặt toàn bộ mã đó vào trong một 'try {} catch (Exception e) {}' vì tôi không muốn điều đó có hiệu lực gì cả. Ngay cả khi tôi không nhận được bất cứ điều gì trở lại Nó sẽ là tốt. Tôi đồng ý điều này sẽ là một trường hợp khá mơ hồ, nhưng hãy cho tôi biết nếu điều đó vẫn sẽ sai. – zidarsk8

1
  • a) Thực hành không tốt, đặt mã hoàn chỉnh bên trong khối thử.

    • a1) Bên cạnh việc bắt ngoại lệ, khối thử là tài liệu có thể xảy ra ngoại lệ. Vì vậy, đặt nó gần với nguyên nhân, bạn có trong tâm trí.
    • a2) Trong trường hợp xấu, bạn có tệp để đọc và thêm tệp sau để viết, nhưng ngoại lệ của bạn (FileNotFoundException) chỉ được ghi với ý nghĩ đầu tiên. Một phạm vi nạc quanh những nơi có vấn đề sẽ giúp bạn, xác định các vấn đề khác.
  • b) Không bắt cơ bản Ngoại lệ để hoàn thành hoặc tránh nhiều khối catch. Nếu bạn muốn ghi vào một tập tin, nhiều thứ có thể sai: Thiếu quyền, tên tập tin bất hợp pháp, không còn khoảng trống trên thiết bị, .... Nếu bạn trình bày cho người dùng một thông báo chung ("Không thể ghi tập tin" + tên), anh ta không biết phải làm gì. Hãy càng cụ thể càng tốt và bạn có thể thông báo cho anh ta rằng "Chỉ còn 20 MB trên thiết bị" + devicename + "Chúng tôi cần thêm 8 MB (tổng cộng 28 MB), vui lòng giải phóng dung lượng và lặp lại hoặc chọn một thiết bị khác!") . Nếu bạn bắt được "Ngoại lệ", rất có thể là cao, bạn đang nghĩ đến một ngoại lệ nào đó, nhưng một trường hợp khác xảy ra và không được xử lý đúng cách, bởi vì khối catch không được viết với khả năng đó. Cơ hội tốt nhất để tìm ngoại lệ này là, để cho nó bật lên, hoặc, để đăng nhập, nếu các nhật ký được kiểm soát thường xuyên.

Nó có thể là sự khác biệt giữa phát triển ứng dụng, đơn giản được người dùng cuối sử dụng hoặc bằng cách phát triển API, được các nhà phát triển khác sử dụng. Trong một API, bạn thường muốn bao gồm một ngoại lệ thành một ngoại lệ riêng, để giúp người dùng api của bạn dễ dàng xử lý nó hơn, và nếu bạn có một cách thống nhất để xử lý các ngoại lệ. Nếu mã của bạn có thể ném nhiều trường hợp ngoại lệ, và sẽ dẫn đến mã khách hàng xấu xí, nơi khách hàng của bạn sẽ cần phải xác định một loạt các trường hợp ngoại lệ hơn và hơn nữa, bạn thường quấn ngoại lệ và rethrow họ:

try { 
... 
} 
catch {FileNotFoundException fnfe} 
{ 
    throw new MyApiException (fnfe); 
} 
catch {PermissionDeniedException pde} 
{ 
    throw new MyApiException (pde); 
} 
catch {IOException ioe} 
{ 
    throw new MyApiException (ioe); 
} 

Bằng cách đó , khách hàng của bạn có thể quyết định, cách xử lý ngoại lệ và sẽ tìm loại ngoại lệ cụ thể, nếu quan tâm, bên trong ngoại lệ của bạn.

Như Landei chỉ ra, trong Java 7 sẽ có một kỹ thuật đơn giản, để bắt nhiều trường hợp ngoại lệ, nhưng không chỉ như vậy với một lớp cha chung, xem this link here

+0

May mắn là đa điểm mới trong Java 7. Xem http://www.baptiste-wicht.com/2010/05/better-exception-handling-in-java-7-multicatch-and-final-rethrow/ – Landei

+1

50% dân số Java đã không chấp nhận đơn giản cho vòng lặp, và bạn đang nói về Java-7? Có lẽ bạn là người dùng scala-người dùng đầu tiên, phải không? ;) –

+0

Vâng, tôi là một kẻ thích nghi sớm ... – Landei

1

Bọc mã tại điểm mà bạn thực sự có thể xử lý ngoại lệ và nơi bạn có thể xử lý lỗi. Nếu bạn không thể xử lý lỗi trong hàm, thì đừng quấn mã trong khối try/catch.

tôi không biết cho java, nhưng trong C++ bạn nên bắt bằng cách tham chiếu const:

try 
{ 
    // code that can throw an exception 
} 
catch (const SomeExceptionType & error) 
{ 
    // handle the error 
} 
1

C++ không phải là Java hoặc C# hoặc ... mà bạn cần catch (hoặc finally) khoản để dọn sạch sau bản thân bạn. Trong C++, RAII thực hiện điều đó. Do đó, tôi hiếm khi viết các câu lệnh try/catch trong C++, đến mức tôi xem nó là một mã nguồn.

Vì vậy, thay vì suy nghĩ xem bạn nên sử dụng kiểu mã nào kết hợp với try/catch, bạn nên tự hỏi liệu mình có cần try/catch không.

+0

+1 cho ** mã mùi **. –

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