2012-10-21 38 views
7
Object o1 = new Object(); 
Object o2 = new Object(); 
//o1=o2; 
System.out.println(o1.equals(o2)); 

它返回false。如果評論被刪除,它可以返回true對Java中的String和Object使用equals()方法


爲什麼對String類不適用同樣的東西?

String s1=new String(); 
String s2=new String(); 
System.out.println(s1.equals(s2)); 

它返回true。爲什麼? (因爲String使用實習生或其他涉及?)

回答

17

因爲equals() for String比較內容,而不是對象本身。

公共布爾等於(object對象)

比較此字符串指定的對象。當且僅當參數不爲null並且是表示與此對象相同的字符序列的String對象時,結果才爲true。

/* String.equals() */ 
public boolean equals(Object anObject) { 
    if (this == anObject) { 
     return true; 
    } 
    if (anObject instanceof String) { 
     String anotherString = (String)anObject; 
     int n = count; 
     if (n == anotherString.count) { 
      char v1[] = value; 
      char v2[] = anotherString.value; 
      int i = offset; 
      int j = anotherString.offset; 
      while (n-- != 0) { 
       if (v1[i++] != v2[j++]) 
        return false; 
      } 
      return true; 
     } 
    } 
    return false; 
} 

(鏈接到的String.equals()源)

對戰equals for Object

的等於爲Object類方法實現對象上差別可能性最大的等價關係;也就是說,對於任何非空參考值xy,當且僅當xy指向同一對象(x == y具有值true)時,此方法返回true。

/* Object.equals() */ 
public boolean equals(Object obj) { 
    return (this == obj); 
} 

(鏈接到的Object.equals()源)

另外,不要忘記equals()功能的合同:

equals方法實現上非等價關係空對象引用:

  • 它是自反:對於任何非空參考值x,x.equals(x)應該返回true。
  • 這是對稱:對於任何非空引用值xyx.equals(y)應返回true當且僅當y.equals(x)返回true。
  • 這是傳遞:對於任何非空引用值xyz,如果x.equals(y)回報truey.equals(z)回報true,然後x.equals(z)應該返回true
  • 它是一致:對於任何非空引用值xy,的x.equals(y)多次調用始終返回true或始終返回false,沒有設置中使用的信息等於在對象上比較被修改。
  • 對於任何非空參考值x,x.equals(null)應返回false

同時推薦閱讀:

+0

除了Object類外,同樣的事情發生在我們創建的類中。爲什麼?它使用'Object'類方法嗎? – Tiny

+0

@Tiny如果你沒有在你的類中重寫equals,它將繼承Object的equals方法。 – assylias

+0

@Tiny因爲每個類都從Object下降。你應該爲你自己的類重寫'equals()'和'hashCode()'方法,否則它們將使用'Object'類的方法。 – ppeterka

8

equalsObject比較內存引用。
這就是爲什麼它是錯誤的,因爲它們是不同的Object s
equals對於String被覆蓋以基於字符進行比較。
您有2個空的String對象,這就是爲什麼equals返回true

+0

'o1 == o2'和'o1.equals(o2)'是否相同(都是問題中指定的對象)?他們似乎是從規範相同。 – Tiny

+0

是的。 Object的'equals'確實:'return this == o2' – Cratylus

2

Object類中實現的equals只比較引用。這裏是源代碼:

public boolean equals(Object obj) { 
return (this == obj); 
} 
+0

'o1 == o2'和'o1.equals(o2)'是否相同(都是問題中指定的對象)?他們似乎是從規範相同。 – Tiny

+0

@Tiny只有在你的第一種情況下,當你創建Object類的兩個實例。在你的第二個案例中,你創建了String類的實例,它覆蓋了equals方法,然後比較兩個對象,看看它們裏面是否有相同的文本。 –

+0

謝謝。消除了我的懷疑。 – Tiny

2

等於如果您希望使其以某種其他方式行爲,則方法需要在類內部重寫。默認情況下,它會檢查兩個引用是否引用同一個對象。

+0

'o1 == o2'和'o1.equals(o2)'是否相同(都是問題中指定的對象)?他們似乎是從規範相同。 – Tiny

4

==比較對象/串/任何

.equals()設計爲使用對象的內部狀態進行比較的地址。

所以:

new Object() == new Object() => false - 在存儲器中的不同地址兩個單獨的對象。

new String("a") == new String("a") => false - 相同的情況 - 兩個單獨的字符串對象的地址。

new String("a").equals(new String("a")) => true - 地址不一樣,但Java會帶一個對象狀態('a'),並與其他對象狀態('a')進行比較會發現它們相等,並將報告爲真。

使用equals()方法,您可以按照任何方式對比較進行編碼,這對您的程序而言是適當的。

intern()是有點不同的故事。它旨在爲相同的字符序列返回相同的對象(地址)。當您多次構建相同的字符串時,減少所需的內存量非常有用。

new String("aaa").intern()將在機器內存中尋找是否有人在之前創建了「aaa」字符串,並返回字符串的第一個實例...如果找不到 - 當前的將被列爲第一個, 「aaa」.intern()和新的String("aaa").intern()("a"+"aa").intern()將返回該「第一個」實例。

注意:"aaa".intern()不是很快的操作,如果你將實習所有的字符串 - 你會節省一些內存,但會鬆動相當多的CPU工作。

+0

'o1 == o2'和'o1.equals(o2)'是否相同(都是問題中指定的對象)?你知道嗎? – Tiny

1

equals()Object類的方法不知道如何比較字符串,它只知道如何比較對象。爲了比較字符串,一個字符串類將會覆蓋equals()方法並比較字符串。

Object.equals()將僅比較參考,其中String.equals()將比較值。

相關問題