2014-02-08 69 views
7

考慮下面的Java代碼:Java的等式操作符是否可交換?

Integer foo = bar(); 
if(foo == 5) ...; 
if(5 == foo) ...; 

這些是比較平等 - 尤其是在foonull的可能性?他們擴大到foo.getValue() == 55 == foo.getValue(),或更類似於foo.equals(new Integer(5))new Integer(5).equals(foo)或其他東西?可能一個或另一個或兩個或沒有投擲NPE?

+1

它看起來像你問他是否是對稱的,不是交換的。普通規則適用於什麼時候拋出一個NPE(雖然對於它的價值,我敢肯定,如果參數爲null,大多數實現將返回'false'。) –

+0

@ user2864740:問題不一樣,因爲我也在問操作數的順序。 – Dolda2000

+0

@ Dolda2000這就是爲什麼我只是把它連接起來。無論如何,[*請參閱答案*](http://stackoverflow.com/a/3352798/2864740) - 它包含許多信息。 – user2864740

回答

1

JLS

15.21.1。數值相等運算==和!=

如果相等運算符的操作數是兩個數字類型的,或 一個是數字型的,另一種是可兌換(§5.1.8)到 數值類型,二進制數字對操作數 (§5.6.2)執行提升。

而且從5.1.8相關規則是:

如果r是整數類型的引用,則取消裝箱轉換 ř轉換成r.intValue()

而5.6.2說:

5.6.2。二元數值提升

當經營者申請的二進制數值提升到一對 操作數,每個都必須表示的值可以轉換爲 數字類型,適用下列規則,依次是:

如果任何操作數都是引用類型,它將經過拆箱 轉換(第5.1.8節)。

這意味着if(foo == 5) ...;的含義一樣if(foo.intValue() == 5) ...;if(5 == foo)意味着if (5 == foo.intValue())。 如果foo等於null那麼在任何情況下您都將獲得NPE。

+1

謝謝!規範中的引用使得相當清楚發生了什麼。 – Dolda2000

+0

值得注意的是,由於Integer是最終的,所以你不能像重寫intValue()那樣瘋狂。:) –

1

==對稱;也就是說,對於任何值xy,(x == y) == (y == x)。這是由JLS §15.21.1爲數字提供給我們的保證,對於引用類型(或不是原始值的所有內容),§15.21.3

它也可以被看作是傳遞,因爲如果三個值x, y, z存在,x == y && y == z,然後x == z。這再次由相同的JLS規範提供 - 僅僅重複以減輕公共變量y的問題。

real問題在於與自動裝箱相關的問題;當你進入取消箱null,然後by the JLS,你會得到一個NullPointerException - 獨立於你接下來要做的比較操作。

有效:

  • 您有該比較的一側上的盒裝原語類型,而在另一基元。兩者的價值尚未考慮。

  • 鑑於原始的will force numerical comparison由於它是一個盒裝原語的值,因此Java將嘗試解開盒裝值。

  • 您無法開箱取件null,因此NullPointerException

這(種),其中在equals()步驟 - 通過合同,如果他們確實是同一事物的兩個非空的情況下,必須等同於對方。如果這兩個值中的任一個(但不是兩個)都是null,那麼它們不是相同的實例。

我說「有點」,因爲真的沒有什麼可以在Object#equals上執行所謂的合同;你可以(通過一些努力)寫出一個不對稱的方法,儘管人們會問你爲什麼要這麼做。

+0

第二個屬性是傳遞性,而不是交換性。 –

+0

謝謝你,我已經糾正它。 – Makoto

+0

實際上,* symmetric *是關於二元關係使用的術語,而* commutative *是二元操作的術語。 '=='當然可以被認爲是兩種,但我認爲它主要是作爲一種手術(我認爲這是合理的,因爲我主要對其副作用感興趣,而不是作爲一種關係)。 – Dolda2000

0

1)有1和2

2)編譯器之間沒有差異轉化foo == 5foo.intValue() == 5(outboxing)

3)如果foonull NPE在運行時拋出

相關問題