簡體   English   中英

toString(),==,equals()對象方法如何在引用和基元類型上以不同或相似的方式工作?

[英]How does the toString(), ==, equals() object methods work differently or similarly on reference and primitive types?

toString()方法, ==運算符和equals()方法如何在引用和基元類型上以不同或相似的方式工作?

對於常規類型(包括String):

  • ==比較對象引用。 它測試兩個對象引用是否相等; 即如果他們引用同一個對象。
  • equals(Object)測試此對象是否“等於”另一個對象。 “等於”意味着取決於對象的類如何定義相等性。 java.lang.Object類將equals(other)定義為this == other ,但許多類重寫此定義。
  • toString()提供了對象到String的簡單轉換。 結果String的格式和內容是特定於類的,並且(從java.lang.Object契約的角度來看)不能保證它有意義。

對於(真)原始類型:

  • ==比較類型的值,和
  • 未定義equals()toString() Java不允許您在原始值上調用方法。

然而,由於在某些情況下 Java語言表示原始類型可以“自動裝箱”以給出基本類型的相應包裝類型的實例,因此這很復雜。 例如, int對應於java.lang.Integer ,依此類推。 對於包裝類:

  • ==的定義與任何其他引用類型相同,
  • equals()比較包裝的值,和
  • toString()格式化包裝的值。

工程中的扳手如下圖所示:

int a = ...
int b = a;
Integer aa = a;        // autoboxing occurs
Integer bb = b;        // autoboxing occurs

assert a == b;         // always succeeds
assert aa.equals(bb);  // always succeeds
assert aa == bb;       // sometimes succeeds, sometimes fails.

最后一次失敗的原因是JLS不保證給定原始值的自動裝箱將始終給出相同的包裝器對象。 它在某些情況下(例如小整數),而不會用於其他情況(例如大整數)。

從上面的示例中學到的教訓是,在引用類型上使用==時需要非常小心。 只有當你真的要測試兩個引用是否屬於同一個對象時才使用它。 如果您只想測試對象是否“相等”而沒有調用equals()的開銷,請不要使用它。

(另請注意, String是另一種類型,其中==在許多情況下會給你錯誤的答案;請參閱如何比較Java中的字符串?

對於引用類型,==將比較實際引用(對象所在的內存位置),其中equals方法執行數據比較。

出於性能原因,JVM有時會“字符串實例化”您的不可變字符串。 導致這種情況:

String a = "abc";
String b = "abc";
if (a == b){ 
    //The if statement will evaluate to true, 
    //if your JVM string interns a and b, 
    //otherwise, it evaluates to false. 
}

http://en.wikipedia.org/wiki/String_interning

'=='運算符適用於您擁有的基本類型,在引用對象的情況下,它是引用本身。 這是a == b會將原始類型的值作為int進行比較,但會比較引用類型的引用(而不是值)。 兩個引用類型不同但具有相同值的對象將在調用equals()方法時返回true ,但a == b將為false。

對於基本類型,在調用方法時,類型先前被轉換(加框)為引用類型,然后調用該方法。 這意味着對於基本類型, a == b將產生與a.equals(b)相同的值,但在后一種情況下,在調用equals()方法之前會創建兩個臨時的盒裝對象。 這將使CPU操作中的操作更加昂貴,這可能是也可能不是問題,這取決於它發生的位置。

也就是說,要比較基本類型值,您應該使用== ,而要比較引用類型值,您應該使用.equals()方法。

toString()方法也是如此。 在引用類型對象上調用時,它將調用適當的方法並生成一個String。 當調用基本類型時,類型將被自動裝箱,然后將在臨時對象中調用該方法。 在這種情況下,您可以調用相應的toString()靜態方法(即對於int調用Integer.toString( myint ) ),這將避免創建臨時對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM