2013-08-28 63 views
10

Tôi mới sử dụng Java và vừa mới xem một hướng dẫn sử dụng từ khóa "Ném" trong một phương thức. Tôi đã thực hiện một ít nghiên cứu về điều này nhưng vẫn không thực sự hiểu nó."Ném" làm gì và nó hữu ích như thế nào?

Từ những gì tôi đã thấy cho đến nay, nó nói với trình biên dịch rằng một ngoại lệ nhất định có thể được ném vào phương pháp cụ thể đó. Tại sao chúng ta cần phải nói cho trình biên dịch này? Tôi đã thực hiện nhiều chương trình bằng cách sử dụng chỉ là một câu lệnh try-catch trong các phương thức của tôi và nó đã làm việc tốt - chắc chắn đó là những câu lệnh try-catch quản lý các ngoại lệ, đúng không?

+0

Java sử dụng ném khoản để nói với trình biên dịch rằng phương pháp có thể ném ngoại lệ là đúng. Nhưng nó cũng cảnh báo người gọi về ngoại lệ đặc biệt có thể xảy ra khi gọi phương thức đó. Vì vậy, người gọi phương pháp có thể thực hiện một số bước dựa trên điều đó. –

Trả lời

32

Bạn có thể quản lý ngoại lệ trong vòng một phương pháp sử dụng trycatch như bạn nói. Trong trường hợp đó, bạn không cần sử dụng throws. Ví dụ:

public void myMethod() 
{ 
    try { 
    /* Code that might throw an exception */ 
    } 
    catch (SpaceInvadersException exception) { 
    /* Complicated error handling code */ 
    } 
} 

Nhưng giả sử bạn có hàng nghìn phương pháp, tất cả đều có thể ném SpaceInvadersException. Sau đó, bạn sẽ phải viết tất cả các mã xử lý lỗi phức tạp một nghìn lần. Tất nhiên, bạn luôn có thể tạo một lớp học ErrorHandler với phương thức dealWithSpaceInvadersException() mà bạn có thể gọi từ họ, nhưng bạn vẫn bị kẹt với một nghìn khối try - catch.

Thay vào đó, bạn thông báo cho trình biên dịch rằng mỗi nghìn phương thức này có thể ném SpaceInvadersException.Sau đó, bất kỳ phương thức nào gọi một trong các phương pháp này cũng cần phải tự xử lý lỗi bằng cách sử dụng try - catch hoặc bằng cách thông báo cho trình biên dịch rằng có thể ném SpaceInvadersException. Này được thực hiện bằng cách sử dụng từ khóa throws, như thế này:

public void myMethod() throws SpaceInvadersException 
{ 
    /* Code that might throw an exception */ 
} 

public void callingMethod() 
{ 
    try { 
    myMethod(); 
    } 
    catch (SpaceInvadersException exception) { 
    /* Complicated error handling code */ 
    } 
} 

Trong trường hợp đó, bạn cần phải thông báo cho trình biên dịch rằng myMethod có thể ném một SpaceInvadersException. Điều này có nghĩa là bạn không thể gọi phương thức đó mà không xử lý ngoại lệ theo một cách nào đó (try - catch hoặc sử dụng từ khóa throws trên phương thức gọi). Nếu throws không có ở đó, bạn có thể gọi phương thức mà không thực hiện bất kỳ xử lý ngoại lệ nào và nhận ngoại lệ không được xử lý ở bất kỳ đâu trong chương trình (điều này sẽ là xấu).

Vì cách tốt nhất là tránh trùng lặp mã, tốt hơn hết là bạn nên xử lý lỗi ở mức try - catch ở hàm mức cao hơn nhiều so với cách xử lý riêng trong tất cả các phương thức cấp thấp . Đó là lý do tại sao cơ chế này tồn tại.

+3

+1 - Câu trả lời hay nhất hiện nay. Những ví dụ hay. –

+0

Tôi hiểu câu trả lời này nhiều hơn tất cả những người khác, mặc dù họ đều hữu ích theo cách riêng của họ. Cảm ơn bạn. – PotWashMike

+0

Không sao cả! Tôi vui vì tôi đã có thể giúp đỡ. –

2

Cao hơn đúng, một số phương pháp sẽ phải nắm bắt ngoại lệ bị ném. Cũng giống như bạn đã nói, đó là các khối try-catch quản lý chúng.

Có một ngoại lệ, và đó là RuntimeException, mà bạn không cần khai báo phần ngoại lệ ném. RuntimeException (và tất cả các lớp con của nó) được gọi là các ngoại lệ không được kiểm soát, sau đó bạn thường không thể phục hồi.

4

Từ khóa throws tuyên bố rằng ngoại lệ có thể được ném ra của phương pháp.

Bạn cũng có thể sử dụng khối catch để bắt ngoại lệ bên trong phương thức. Nếu bạn nắm bắt nó và không rethrow nó, sau đó nó không được ném ra khỏi phương pháp.

Tờ khai throws cho phép xác minh thời gian biên dịch rằng một phương pháp hoặc là:

  • Catches các trường hợp ngoại lệ nó ném, bao gồm những người từ các phương pháp mà họ gọi.
  • Hoặc khai báo chúng để người gọi có thể thực hiện kiểm tra tương tự.
0

Ném là cơ chế để ném ngoại lệ cho phương thức gọi. Điều này thường được sử dụng để ném ngoại lệ đến một mức độ mà nó có thể được xử lý.

Ví dụ thực tế là ứng dụng dựa trên gui với một số logic phụ trợ. Nếu có sự cố trong chương trình phụ trợ, bạn có thể muốn hiển thị thông báo thích hợp cho người dùng. Vì vậy, từ backend của bạn, bạn có thể ném ngoại lệ tối đa các lớp UI của bạn và sau đó có thể hiển thị một tin nhắn cho phù hợp.

+1

"Ném" không ném ngoại lệ - nó * tuyên bố * rằng một ngoại lệ có thể bị ném. –

+0

@AndyThomas Hoàn toàn đồng ý, nhưng nếu có ném trong khai báo phương pháp, điều đó có nghĩa là bạn muốn ném một ngoại lệ. –

+0

Điều đó có nghĩa là người gọi nên giả sử phương pháp của bạn có thể ném ngoại lệ đã khai báo. Phương pháp của bạn có thể không bao giờ thực sự ném ngoại lệ. Đoạn đầu tiên của bạn cần chỉnh sửa; nó cho thấy rằng "ném" gây ra ngoại lệ được ném. –

0

Chương trình Java ném ngoại lệ bất cứ khi nào nó xảy ra. Tuy nhiên, sẽ có lúc bạn muốn ném ngoại lệ theo cách thủ công, cho từ khóa throws này được sử dụng.

Ví dụ: class Abc { public static void main(String args[]) throws IOException{ }}

+0

Tôi đã hết phiếu bầu, nhưng điều này về cơ bản là không chính xác. – chrylis