2010-07-13 69 views
16

我在閱讀最佳實踐和推薦編碼Java手冊,我認爲這是可疑的。Java:「xx」.equals(變量)優於variable.equals(「xx」),TRUE?

Recomendation:

String variable; 

"xx".equals(variable) // OK 

variable.equals("xx") //Not recomended 

由於NullPointerException異常的防止外觀不控制

這是真的嗎?

+3

如果你正在編寫一份技術手冊,你需要擔心更大的語法問題,而不是像這樣的小編碼警告。 – Zak 2010-07-13 19:47:42

+6

@Zak,那真的沒有關係。你怎麼知道手冊將會是英文的?也許Xerg用其他語言流利地寫道,並且正在用該語言創建手冊。所有回答的人都設法弄清楚問題的癥結所在。 – 2010-07-13 19:55:33

+1

我不寫任何手冊。我只是在檢查。請原諒我的英語,我是一個比作家更好的讀者。 – Xerg 2010-07-13 20:04:22

回答

23

這是一種非常常見的技術,如果變量爲空而不是拋出NullPointerException,則會導致測試返回false。但我想我會有所不同,並說我不會認爲這是你應該遵循的建議。

  • 我絕對認爲這是所有Java程序員都應該知道的東西,因爲它是一個常見的習慣用法。
  • 這也是一個有用的技術,使代碼更簡潔(你可以同時處理null和not null的情況)。

但是:

  • 它使你的代碼難以閱讀:"If blue is the sky..."
  • 如果剛剛確認您的參數不是null上一行則是不必要的。
  • 如果您忘記測試null,並且某人確實帶有一個您認爲沒有期待的空參數,那麼NullPointerException未必是最糟糕的結果。假裝一切都很好,一直持續到最終最終失敗並不是一個更好的選擇。快失敗是好事。

我個人認爲我不要認爲應該在所有情況下使用這種技術。我認爲這應該留給程序員根據具體情況進行判斷。重要的是要確保你已經以適當的方式處理了這個空案,並且你怎麼做取決於情況。檢查空值的正確處理可能是測試/代碼評審準則的一部分。

+1

「它使你的代碼更難閱讀:」如果藍色是天空......「 - 否則稱爲yoda條件 - http:// en。wikipedia.org/wiki/Yoda_conditions – chrismarx 2015-05-08 19:17:44

10

確實如此。如果variable是你的榜樣null

variable.equals("xx"); 

將拋出一個NPE,因爲你不能叫一個空對象的方法(equals)。但是

"xx".equals(variable); 

只會返回false沒有錯誤。

+0

但''''''''應該可能是一個錯誤。 – 2010-07-13 21:55:20

+0

@Tom:好吧,也許吧。我遇到了一些應該是錯誤的情況,以及其他不應該出現的情況。我實際上同意馬克·比爾斯的看法,認爲在個案基礎上對其進行評估是有意義的。 – 2010-07-14 00:33:53

3

這是在Java(和C#)程序中使用的常用技術。第一種形式避免了空指針異常,因爲在常量字符串"xx"上調用.equals()方法,該字符串永遠不會爲null。與null相比,非空字符串爲false。

如果您知道variable永遠不會爲空(並且您的程序在某些其他方式中不正確(如果它永遠爲空),那麼使用variable.equals("xx")就沒有問題。

4

其實我覺得原來的推薦是真的。如果您使用variable.equals("xx"),那麼如果variable爲空,則將獲得NullPointerException。將常量字符串放在左側可避免這種可能性。

這個防禦是否值得許多人認爲是非自然的成語,這取決於你。

+1

Peronsalized我發現「Yoda版本」非常尷尬閱讀,但它確實避免了空指針異常。另一種方法是's!= null && s.equals(「xx」)',這是更多的類型,並需要幾個額外的納秒來做額外的比較。 – Jay 2010-07-13 19:56:47

0

如果您需要檢查null,我發現這比 if (variable != null && variable.equals("xx"))更好。這更多是個人喜好的問題。

2

確實,使用任何對象的屬性可以幫助您避免NPE。

但這就是爲什麼我們有Exceptions來處理這些事情。

也許如果你使用「xx」.equals(變量),你永遠不會知道變量的值是否爲null或者只是不等於「xx」。海事組織最好知道你的變量是空值,所以你可以重新分配它,而不是忽略它。

0

你對檢查的順序是否正確 - 如果變量爲null,對字符串常量調用.equals將會阻止NPE - 但我不確定我認爲這是一個好主意;我個人稱之爲「slop」。

當您沒有檢測到異常情況但實際上會創建習慣以避免檢測到異常時,Slop就會出現。在一段較長的時間內將空值作爲字符串傳遞將最終導致可能模糊且難以找到的錯誤。

slop的編碼是「Fail fast fail hard」的反義詞。

將null作爲字符串使用可能會偶爾產生一個很好的「特殊」值,但是您試圖將其與某些事物進行比較表明您對該系統的理解不完整(最好) - 您越早發現這個事實越好。

另一方面,默認情況下所有變量都是最終的,使用泛型和最小化所有對象/方法的可見性都是減少斜率的習慣。

0

作爲一個側面說明,這裏是一個設計模式,其中該代碼建議可能沒有任何區別,因爲字符串(即Optional<String>)永遠不會空,因爲從設計模式.isPresent()調用的:

Optional<String> gender = Optional.of("MALE"); 
if (gender.isPresent()) { 
    System.out.println("Value available."); 
} else { 
    System.out.println("Value not available."); 
} 
gender.ifPresent(g -> System.out.println("Consumer: equals: " + g.equals("whatever"))); 
相關問題