2012-05-29 274 views
20

今天有人在Java中使用了return關鍵字。我寫了一個簡單的for循環來驗證某個數組中的東西。假設array是長度的數組n,這是我的代碼:返回for循環或外部循環

for(int i=0; i<array.length; ++i){ 
    if(array[i]==valueToFind) return true; 
} 
return false; 

現在有人告訴我,這不是很好的編程,因爲我使用的是循環中的return聲明,這將導致垃圾回收出現故障。因此更好的代碼將是:

int i = 0; 
while(i<array.length && array[i] != valueToFind) ++i; 
return i != array.length; 

問題是,我不能想出一個適當的補充,爲什麼第一個循環不是一個好的做法。有人可以給我一個費用嗎?

+0

那個人究竟做了什麼,作爲第一個不好的原因?與GC打交道? – Poindexter

+7

如果GC發生故障,這是JVM的問題,而不是您的程序...您的代碼完全有效。 –

+0

「這會導致垃圾回收失靈」:您能詳細說明嗎? – assylias

回答

47

現在有人告訴我,這不是很好的編程,因爲我使用的是循環中的return語句,這將導致垃圾回收出現故障。

這是不正確的,並建議你應該以一定的懷疑態度對待來自該人的其他建議。

的「只有一個return語句」(或更一般,只有一個出口點)是,你必須自己管理所有資源語言重要的口頭禪 - 這樣你可以確保你把你所有的清理工作代碼在一個地方。在Java中它非常有用:只要你知道你應該返回(以及返回值應該是什麼),只需返回。通過這種方式閱讀起來更簡單 - 您不必採用其餘任何方法來計算還會發生什麼(除finally塊之外)。

+4

單個return語句是我以前工作的代碼約定的一部分。我發現它導致大量的嵌套,並且更難以閱讀代碼。 – brain

+2

@brain:確實。這通常是人們在不理解*理由的情況下接受一個想法的結果*爲什麼在某種情況下它是一個好主意。 –

+1

在出現異常情況下,單個退出只是不可行的,因爲幾乎任何非平凡的代碼都可能引發一個退出。最好在這裏使用語言流,而不是強迫代碼根據某些在不同環境/語言中可能有意義的規則行事。 –

6

現在有人告訴我,這不是很好的編程,因爲我 使用一個循環中return語句,這將導致垃圾收集 發生故障。

這是一堆垃圾。除非在課堂或其他地方有其他參考資料(封裝很重要的原因),否則方法內的所有內容都將被清除。作爲一個經驗法則,使用一個return語句通常會更好,因爲它更容易確定方法將退出的位置。

就個人而言,我會寫:

在所有語言中提倡在任何功能使用單一return語句
Boolean retVal = false; 
for(int i=0; i<array.length; ++i){ 
    if(array[i]==valueToFind) { 
     retVal = true; 
     break; //Break immediately helps if you are looking through a big array 
    } 
} 
return retVal; 
+5

梅;編寫最易讀的代碼通常會更好,無論這意味着多少返回語句。例如,如果您有一堆警戒條款,則每個(IMO)在發生故障時應立即返回。 –

+0

作爲一個方面說明,在這種方法中沒有GC,因爲這裏沒有對象分配。 –

+0

肯定與戴夫同意 - 我不明白爲什麼「方法將退出」本身是重要的。重要的是你可以輕鬆地遵循該方法的邏輯。 –

3

已經有方法。然而,在某些代碼中可能是不可能的,但有些人確實爲此付出了努力,但最終可能會使代碼更加複雜(如更多代碼行),但另一方面更容易遵循(如邏輯流)。

這不會以任何方式搞亂垃圾收集!

更好的方法是設置一個布爾值,如果你想聽他的話。

boolean flag = false; 
for(int i=0; i<array.length; ++i){ 
    if(array[i] == valueToFind) { 
     flag = true; 
     break; 
    } 
} 
return flag; 
2

有些人認爲一種方法應該有一個退出點(例如,只有一個return)。就我個人而言,我認爲試圖堅持這一規則會產生難以閱讀的代碼。在你的例子中,只要你找到你要找的東西,立即返回它,它很清楚,而且效率很高。

Quoting the C2 wiki:

具有用於功能的單一入口和單一出口的原始意義在於,它是StructuredProgramming的原始定義的一部分,而不是散漫轉到麪條式代碼,並允許在一個乾淨的數學分析這個基礎。

既然結構化編程早已勝出,那麼現在沒有人會特別關心這個問題,而其餘的網頁主要是關於最佳實踐和美學等,而不是關於結構化編程結構的數學分析。

1

該代碼在兩種情況下都是有效的(即將編譯和執行)。

我的一位在大學的講師告訴我們,這是不希望有任何循環continuereturn報表 - forwhile。原因在於,在檢查代碼時,不能立即清楚執行循環的全部長度,還是要求returncontinue生效。

查看Why is continue inside a loop a bad idea?舉例。

需要記住的一點是,對於像這樣的簡單場景,它不會(IMO)問題,但是當你有複雜的邏輯來確定返回值時,如果你有一個單一的返回語句而不是幾個。

關於垃圾收集 - 我不知道爲什麼這將是一個問題。