2010-02-04 51 views
17

我有一個函數在執行某些可能會引發異常的情況下循環。看起來像這樣:在Java中拋出異常的鏈接列表

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

導致異常的錯誤是可恢復的。它可能類似於單個更新語句中的SQL錯誤,其中while循環執行一系列更新語句。或者單個數據中的解析錯誤,其中循環正在處理多個數據片段。我需要在鏈中進一步傳遞異常,以便程序的GUI部分可以處理它,處理它並將錯誤傳遞給用戶。但我不想在這個特定的函數中殺死循環。它正在做的其他事情可能不是無效的。導致異常的錯誤可能不是致命的功能。

所以我的問題是這樣的:建立自定義異常鏈接列表(其中每個異常是一個節點,拋出的異常是列表的頭部)然後拋出列表的頭部是可接受的做法(如果有的話)一旦循環完成?

有沒有人見過這樣做?任何人都可以想到這樣做的任何潛在問題?任何人都可以想到其他更好的方法來處理根本問題:需要通過退出函數來傳遞多個不相關的異常,直到完成它爲止?

這裏有一個如何進行鏈接,並拋出可能會很簡單地實現一個例子:(比我從來沒見過這等)

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

順便說一下。超越你在這裏使用鏈表或不在。有一個'java.util.LinkedList'類可以使用,所以你不必在你的item對象中編程它的功能(在這種情況下,'MyException')。 – helios 2010-02-04 21:04:01

+0

我知道它。我不認爲你可以在這種情況下使用它,因爲列表需要被拋出,LinkedList不是可拋出的。 – 2010-02-04 22:09:08

回答

16

我INTIAL想到的是,一個例外是可能相當大對象(包含堆棧跟蹤),我寧願而不是來存儲它們中的很多。

如發生異常我反而打造的錯誤參數/參數列表,循環結束後,扔填入此列表中的自定義異常(如果列表已經超過0元素)。這似乎是處理這種情況的一種更易於管理的方式。

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

現有函數簽名返回void。你可以簡單地返回失敗對象的列表,或其他一些收集成功和失敗的結構等。 – TREE 2010-02-04 20:49:54

+0

@TREE我相當肯定這是一個例子,而不是實際的方法 – Kevin 2010-02-04 20:51:01

+0

+1,這比我的更加整潔。我修正了你的代碼來聲明'拋出CustomException'。哦,請注意,'Error'是'java.lang'中的現有類。您可能想更改名稱以避免混淆。 – BalusC 2010-02-04 20:58:04

3

你真的需要拋出所有的異常嗎?您如何期望處理個別的無關例外?通常在這種情況下,系統只會報告錯誤並完成它。

如果是這樣,您可能需要收集錯誤消息並將它們添加到自定義的Exception類中並拋出該錯誤消息。

1

如果DoSomething();拋出的異常可能會導致拋出另一個異常的方法相同;這可能是一個問題。換句話說,如果DoSomething();拋出一個異常因爲你沒處理前一個,有可能是unnecesarry錯誤處理。

+0

正確。在這個場景中,我問的不是(理論上)是這種情況,但是,這絕對是要記住的。 – 2010-02-04 20:53:46

3

如果這些例外情況確實無關,因此您無法從get/setCause()中獲益,那麼我寧願將這些信息收集到一個MyException

E.g.

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; 
    } 
} 

更新:Brian處理更整潔的方式正是這種做法。我會選擇,而不是:)

0

國際海事組織,例外應該是你有最後一個資源來處理錯誤。如果可能的話應該避免。因此,您可能想要將錯誤描述(創建錯誤代碼,傳遞消息或有意義的內容)傳遞給GUI,而不是異常本身。

2

實際上,從這樣的函數拋出任何異常可能不是正確的方法來處理這個,如果預計會出現錯誤。我建議要麼返回所有發生的異常/錯誤的列表(數組),要麼提供一個錯誤處理程序對象給可以處理異常的函數。即:

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); 
     } 
    } 
} 

這也讓錯誤處理程序自行收集的錯誤,將它們呈現給用戶或決定,整批的操作已經成爲因爲一些錯誤的空白,並把它自己的異常中止處理早。

+0

我發現這種方法比@Brain Agnew回答更好,原因如下:1.錯誤處理程序允許您根據需要以不同的方式處理不同的異常2.不需要更多地構建錯誤(或某種指示器),因此您正在處理錯誤發生時。 – Stackee007 2017-01-24 00:29:11

1

我認爲你可以傳遞一些回調或監聽器的方法,或設置一個類變量,而不是像x4u那樣拋出列表。

在Java中有一個這樣的接口:java.beans.ExceptionListener