2010-02-04 72 views
17

Tôi có một hàm lặp lại trong khi làm một cái gì đó có thể ném một ngoại lệ. Có dạng như sau:Ném một danh sách liên kết ngoại lệ trong Java

public void myFunction() throws MyException { 
    while(stuff) { 
     try { 
      DoSomething() // throws an exception 
     } 
     catch (Exception ex) { 
      throw new MyException(some, stuff, of, mine, ex); 
     } 
    } 
} 

Lỗi gây ra ngoại lệ có thể phục hồi. Nó có thể giống như một lỗi SQL trong một câu lệnh cập nhật duy nhất trong đó vòng lặp while thực thi một loạt các câu lệnh cập nhật. Hoặc lỗi phân tích cú pháp trong một phần dữ liệu duy nhất, trong đó vòng lặp đang xử lý nhiều phần dữ liệu. Tôi cần phải vượt qua các trường hợp ngoại lệ thêm chuỗi để phần GUI của chương trình có thể xử lý nó, xử lý nó và truyền vào lỗi cho người dùng. Nhưng tôi không muốn giết vòng lặp trong chức năng cụ thể này. Những thứ khác mà nó đang làm có thể không hợp lệ. Lỗi gây ra ngoại lệ có thể không gây tử vong cho hàm. Vì vậy, câu hỏi của tôi là: Có thực hành được chấp nhận để xây dựng danh sách các ngoại lệ tùy chỉnh được liên kết (trong đó mỗi ngoại lệ là nút và ngoại lệ được ném là đầu danh sách) và sau đó ném đầu danh sách (nếu có) khi vòng lặp kết thúc?

Có ai từng xem công việc này chưa? Bất cứ ai có thể nghĩ về bất kỳ vấn đề tiềm năng với việc này? Bất cứ ai có thể nghĩ về cách khác, tốt hơn để xử lý vấn đề gốc: sự cần thiết phải vượt qua nhiều ngoại lệ không liên quan với ra khỏi chức năng cho đến khi nó được thực hiện?

Dưới đây là một ví dụ về cách liên kết và ném có thể được thực hiện rất đơn giản:

public void myFunction() throws MyException { 
    MyException head = null; 
    while(stuff) { 
     try { 
      DoSomething() // throws an exception 
     } 
     catch (Exception ex) { 
      MyException tmp = new MyException(some, stuff, of, mine, ex); 
      tmp.next(head); 
      head = tmp; 
     } 
    } 
    if(head != null) 
     throw head; 
} 
+2

Nhân tiện. Ngoài bạn sử dụng một danh sách liên kết ở đây hay không. Có một lớp 'java.util.LinkedList' sẵn sàng để sử dụng, do đó bạn không phải lập trình chức năng của nó bên trong các đối tượng item của bạn (trong trường hợp này là' MyException'). – helios

+0

Tôi biết điều đó. Tôi không nghĩ rằng bạn có thể sử dụng nó trong trường hợp này, bởi vì danh sách cần phải được ném và LinkedList không phải là một throwable. –

Trả lời

16

suy nghĩ ban đầu của tôi (khác hơn là tôi đã không nhìn thấy điều này) là một ngoại lệ là có tiềm năng khá một đối tượng lớn (có chứa stacktrace) và tôi muốn không phải để lưu trữ nhiều thứ trong số đó. Thay vào đó, tôi sẽ xây dựng một danh sách các tham số/đối số sai khi các ngoại lệ xảy ra, và sau khi hoàn thành vòng lặp, hãy ném một ngoại lệ tùy chỉnh được điền vào danh sách này (nếu danh sách có nhiều hơn 0 phần tử). Điều đó có vẻ là một cách xử lý dễ dàng hơn kịch bản này.

public void myFunction() throws CustomException { 
    List<MyError> errors = new ArrayList<MyError>(); 
    while(stuff) { 
     try { 
      DoSomething() // throws an exception 
     } 
     catch (Exception ex) { 
      errors.add(new MyError(some, stuff, of, mine, ex)); 
     } 
    } 
    if (errors.size() > 0) { 
     throw new CustomException(errors); 
    } 
} 
+0

Chữ ký hàm hiện có sẽ bị hủy. Bạn có thể đơn giản trả về danh sách các đối tượng thất bại, hoặc một số cấu trúc khác thu thập thành công và thất bại, v.v. – TREE

+0

@TREE Tôi khá chắc chắn đó là một ví dụ, không phải là phương pháp thực tế – Kevin

+0

+1, đây là điều thú vị hơn tôi. Tôi đã sửa mã của bạn để khai báo 'ném CustomException'. Oh, lưu ý rằng 'Lỗi' là một lớp hiện có trong' java.lang'. Bạn có thể muốn thay đổi tên để tránh nhầm lẫn. – BalusC

3

Bạn có thực sự cần phải ném tất cả ngoại lệ? Làm thế nào để bạn mong đợi các trường hợp ngoại lệ cá nhân, không liên quan được xử lý? Nói chung trong các trường hợp như thế này, hệ thống sẽ chỉ báo cáo các lỗi và được thực hiện với nó.

Nếu có, bạn có thể chỉ muốn thu thập thông báo lỗi và thêm chúng vào lớp học Exception tùy chỉnh và ném điều đó.

1

Nếu ngoại lệ được ném bởi DoSomething(); có thể gây ra cùng một phương pháp để ném một ngoại lệ khác; điều này có thể là một vấn đề. Nói cách khác, nếu DoSomething(); ném một ngoại lệ bạn không xử lý trước đó, có thể có lỗi không cần thiết để xử lý.

+0

Đúng. Trong kịch bản tôi hỏi về điều này sẽ không (về mặt lý thuyết) là trường hợp, tuy nhiên, điều này chắc chắn là một cái gì đó để ghi nhớ. –

3

Nếu những ngoại lệ đó thực sự không liên quan với nhau để bạn không thể hưởng lợi ích của get/setCause(), thì tôi muốn thu thập thông tin này trong một MyException.

Ví dụ:

public void myFunction() throws MyException { 
    MyException myException = null; 
    while(stuff) { 
     try { 
      DoSomething() // throws an exception 
     } 
     catch (Exception ex) { 
      if (myException == null) { 
       myException = new MyException(); 
      } 
      myException.addException(some, stuff, of, mine, ex); 
     } 
    } 
    if (myException != null) { 
     throw myException; 
    } 
} 

Cập nhật:Brian xử lý chính xác phương pháp này một cách gọn gàng hơn.Tôi sẽ chọn tham gia thay vào đó :)

0

IMO, ngoại lệ phải là tài nguyên cuối cùng bạn có để xử lý lỗi. Nó nên tránh nếu có thể. Vì vậy, bạn có thể muốn vượt qua các mô tả lỗi (tạo ra các mã lỗi, truyền thông điệp, hoặc một cái gì đó có ý nghĩa) cho GUI, và không phải là ngoại lệ chính nó.

2

Thực tế việc ném bất kỳ ngoại lệ nào từ chức năng như vậy có lẽ không đúng cách để xử lý việc này nếu dự kiến ​​sẽ có lỗi. Tôi muốn đề nghị trả lại một List (Array) của tất cả các ngoại lệ/lỗi xảy ra hoặc tốt hơn để cung cấp một đối tượng xử lý lỗi cho hàm có thể xử lý các ngoại lệ. ví dụ:

public interface ErrorHandler 
{ 
    public void handleError(Throwable ex /*, add some context info */); 
} 

public void myFunction(ErrorHandler eh) 
{ 
    while(stuff) { 
     try { 
      DoSomething() // throws an exception 
     } 
     catch (Exception ex) { 
      if(eh != null) 
       eh.handleError(ex); 
     } 
    } 
} 

này cũng cho phép xử lý lỗi hoặc thu thập các lỗi để trình bày chúng cho người sử dụng hoặc quyết định rằng hoạt động toàn bộ lô hàng đã trở thành khoảng trống vì một số lỗi và để ném một ngoại lệ của riêng của nó để hủy bỏ việc xử lý sớm.

+0

Tôi thấy cách tiếp cận này tốt hơn cho câu trả lời @Brain Agnew vì các lý do sau đây 1. Trình xử lý lỗi cung cấp cho bạn xử lý các ngoại lệ khác nhau nếu cần 2. Không xây dựng nhiều mảng lỗi (hoặc một số loại chỉ báo) như bạn đang xử lý lỗi khi chúng xảy ra. – Stackee007

1

Tôi nghĩ bạn có thể chuyển một số gọi lại hoặc người nghe đến phương thức hoặc đặt trong biến lớp và thay vì ném danh sách, như x4u đã làm.

Trong Java, có giao diện cho điều này: java.beans.ExceptionListener

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