2012-11-17 111 views
4

我有以下方法IndexOutOfBoundsException異常返回什麼?

private ArrayList<User> allUsers = new ArrayList<User>(); 

public User getUser(int index) { 
    try { 
     return allUsers.get(index); 
    } 
    catch(IndexOutOfBoundsException e) { 
     // What should I return here?? Say that you want index 0 and no User 
     // exists in the ArrayList allUsers, what should I then return? The 
     // method needs a User to be returned 
    } 
} 

而且我不知道怎麼在這裏做,我敢肯定,這就是它的一個簡單的辦法,但我應該在catch塊返回? Eclipse正在抱怨必須返回User

+8

只需返回空值即可。 – Doorknob

+4

或者沒有發現異常 – Bohemian

+4

讓異常通過; getUser方法的調用者有問題。 –

回答

3

如果沒有用戶發現我會拋出異常。該方法被調用時會捕獲此異常。如果需要,您可以在此修改代碼以使用自定義異常。喜歡的東西:

public User getUser(int index) throws IndexOutOfBoundsException { 
    if(index >= allUsers.size()){ 
     throw new IndexOutOfBoundsException("User doesn't exist"); 
    } 
    return allUsers.get(index); 
} 
+1

「IndexOutOfBoundsException」未被選中。你不需要聲明它。 –

+0

這是真的,我把代碼放在了他想要拋出一個自定義excepction而不是出界的地方,也許他想創建一個UserNotFoundException或者什麼的,他會知道把它放在哪裏。但是你的觀察是非常重要的。 – alemangui

+2

@JanDvorak添加一個throws子句明確地表明這個方法將拋出IndexOutOfBoundsException;這不是必需的,但如果這實際上是其他用戶的API,則可能會有所幫助。 –

11

問自己一個問題:「如果你想索引0並且沒有用戶存在,你應該返回什麼?」並返回你回答的任何內容。

如果你沒有答案,你應該重新拋出異常,或者不要抓住它。

需要注意的是很多時候,答案將返回null,如果是接受的行爲要求一個不存在的用戶。


邊評論:它通常被認爲是「好的做法」不依賴於捕捉異常,但首先測試錯誤條件。在你的情況下,你正在嘗試get一個無效的對象索引,然後反應如果吸氣劑爆炸。相反,我會建議首先測試index參數(確保它至少爲零並且小於allUsers的長度),並且如果測試失敗(返回null或拋出您自己的異常),則測試失敗。

+1

+1,特別是對於這種情況下真正有用的所謂的「副評論」。 –

+0

+1;請注意,一些例外情況(掃描器 - > InputMismatchException)不能被阻止。 –

+0

@JanDvorak我不知道這個特定的例子,但那是當你*有*求助於捕捉拋出的異常。在這個特定的例子中,在絕大多數情況下,防止異常被拋在第一位(*但不一定100%萬無一失,儘管如此)是相當微不足道的。 –

2

不要聽Eclipse。

您有兩種選擇,根據具體情況,兩種選擇都可以是好還是不好。

  1. 您可以返回null
  2. 你可以重新拋出異常(或者說,甚至根本就沒有抓到它),要求調用方法來處理它。

還有幾個變化,但基本的選擇是在上述兩個之間:處理問題到位或委託任務給調用者。

僅憑這些代碼就無法確定哪一個是正確的解決方案,只有您可以知道哪種情況更適合。

無論您選擇哪種方式,最好手動檢查索引(0<=index<allUsers.size()),而不要依賴RuntimeExceptions來獲得正常的程序行爲。

+0

Eclipse'抱怨',因爲每條路徑都需要返回一些東西。所以他應該聽那個(否則它永遠不會編譯)。 –

+0

@MarkRotteveel OP寫道:「Eclipse說一個用戶必須返回」。這是公然不真實的,你也可以拋出一個異常。 – biziclop

+1

解釋Eclipse(或編譯器)試圖傳達什麼可能會更好,而不是簡單地說不聽它。 –

2

假設index是用戶輸入,只需讓IndexOutOfBoundsException傳播並在可以顯示錯誤消息的位置將它捕獲得更遠。

實際上,在嘗試查找同樣的事情之前,您可以先對allUsers.size()驗證index。用戶輸入通常應在儘可能早的時候進行驗證。

4

有很多可能性。其中一些取決於你的信仰。

  • ,因爲傳遞的參數 無效可以拋出IllegalArgumentException。

  • 您可以拋出IndexOutOfBoundsException異常。

  • 如果你想確保客戶端(此方法的調用者)必須採取 照顧它,你甚至可以申報檢查的異常(定義 異常類擴展除外),因爲 拋出:IllegalArgumentException和IndexOutOfBoundsException異常是運行時 異常,這意味着你不必明確地準備自己。

我平時檢查,如果指數在範圍內,如果沒有返回null,因爲它可以返回空值的Javadoc提及是否......

+1

+1,特別是因爲我不得不對'取決於你的信仰'發笑:) –

15

我一般的看法是,你應該永遠也趕不上的例外,你不知道如何處理。特別是在這種情況下,因爲IndexOutOfBoundsExceptionRuntimeException,因此不需要被捕獲 - 您可以讓它沿着調用堆棧傳播。調用者通過列表索引來請求一個對象,因此大概已經知道要索引哪個索引 - 然後,拋出或允許拋出的IndexOutOfBoundsException異常傳播似乎是非常自然的。

唯一的另一個顯而易見的選擇是吞下異常和return null,但我真的不喜歡這樣的方法來處理調用方的這種明顯的錯誤,因爲沒有明顯的返回值。你也可以返回一個特殊User實例(參照空對象模式),但即使這並不能免除責任的調用者來檢查返回什麼。取決於User的接口和實現,這種檢查可能是微不足道的,但它仍然需要在某個地方完成。

如果你想明確的是,該方法可以拋出異常,只是這麼說:

public User getUser(int index) throws IndexOutOfBoundsException { ... } 

或者像@Bela Vizer建議,把它包在一個IllegalArgumentException(這也是一個RuntimeException)。

以及由@lc.指出,這是更好,如果對象試圖訪問它之前存在先檢查自己。處理你自己,你期望而不是依靠get()方法調用拋出異常錯誤的情況。但是,如果例如在檢查和返回之間修改了集合,那麼您應該仍然清楚這樣一個事實,即方法可能會在處拋出這樣的異常。使用多核CPU上的多線程軟件,已知會發生陌生事物。

2

我會回來null,但是,如果你覺得你的應用程序可能會崩潰,因爲這一點,你可以簡單地返回一個「沒有人」用戶是這樣的:

return new User("nobody", ...); 

並處理在功能之外的情況。

另一種方法是拋出異常外處理。

+7

不,只是 - **否**。如果你使用空對象模式,*至少*暴露一個公共的,只讀的'NoSuchUser'實例,你返回並且可以進行比較。或者在某處公開一個公共方法來檢查'User'實例是否是一個真正的用戶。當你走的時候不要做一個。 –

1

您有幾種選擇:

  1. 返回null。如果用戶可以合理地輸入任何索引,請執行此操作。
  2. 不要捕捉異常。如果用戶輸入錯誤數據是完全意想不到的,換句話說,輸入已被檢查,所以這是造成這種情況的「編程錯誤」(或錯誤)。
  3. 拋出檢查異常。如果您覺得呼叫代碼可以並應該處理該問題,請執行此操作。
相關問題