2016-06-17 25 views
0

我們可以通過重寫相應類中的equals/hashcode方法來比較兩個對象,但這兩個對象在我們的寫入方法(equals/hashcode)的上下文中將是相等的!兩個物體的平等意味着什麼嗎?

即使我們發現兩個對象具有相同的所有屬性值,這是否意味着除此之外的任何內容?我的意思是,根據編譯器/ JVM,這兩者將是不同的對象,對吧?我想他們也會擁有兩個不同的記憶位置,不是嗎?我是新來的Java,所以如果我說什麼都很愚蠢,我會很感激,如果你能糾正我,或者如果你需要澄清任何事情,請隨時詢問,但鑑於同樣的事實,我請求所有這些請不要問我完全改變我的問題或其結構。在此先感謝!)

+1

您可以定義平等任何方式你想要的就是這個意思。 – Nozdrum

+3

[Java中==和equals()有什麼不同?](http://stackoverflow.com/questions/7520432/what-is-the-difference-between-vs-equals-in-java ) – user140547

+1

如果用「意思是任何東西」,你的意思是「意味着它們是同一個對象」,那麼沒有。如果是「有意義的」,那麼你的意思是「有意義的」,那麼是的。它意味着你定義它的意思。你需要提出更精確的問題。 – user2357112

回答

0

是理論上它並不重要,但不是所有的應用程序,你寫的?但是每當我比較一個對象時,我知道它是指同一個數據庫記錄,因爲ID是相同的(和類型),所以對我的代碼很有價值。您可以確保您的對象不在列表中,例如,您可以在列表中擁有兩個不同的實例,而您需要數據庫對象的唯一表示列表,那麼.equals函數將變得非常有用。

如果您需要知道它是否是完全相同的實例,您應該不會覆蓋.equals方法。像其他人說,重要的是,它包含相同的文本值,例如兩個字符串:

function foo() { 
    String bar = "I'm cool"; 
    String baz = "I'm cool"; 

    assertTrue(bar.equals(baz)); //true 
    assertTrue(bar == baz); //false 
} 

例子可能是錯的,但是這是這裏的區別。如果重寫equals方法對JVM無關緊要,那麼JVM就沒有良心了。

玩得開心!

0

在你的問題和缺乏連貫性這麼多混淆。你寫:

我們可以通過在各自的類

沒有覆蓋了equals/hashCode方法比較兩個對象,你不知道。你比較,當你正在執行類似,例如兩個對象:

String firstString = "asdf"; 
    int result = firstString.compareTo("asdff"); 

你「比較」當你調用實現ComparablefirstString)的類的對象上compareTo方法,將另一個對象("asdff")作爲該方法的實際參數。就是這樣,它只是名稱的問題(類型的名稱 - 類和方法的名稱)。

關於等號運算符(==)和等號方法之間區別的問題,這又只是一個定義問題。規則在這裏定義https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.21

即使我們發現兩個對象具有相同的所有屬性值,這是否意味着除此之外的任何內容?

什麼物體?這些對象是什麼類型?他們的屬性是什麼類型?這完全取決於他們如何實施。這個問題非常模糊,但我會說,答案是無論如何。在Java程序(或任何其他語言)的背景下,平等並不意味着超出語言規範和代碼定義的任何內容。

我想他們也會擁有兩個不同的內存位置,不是嗎?

實例(如果你不明白的「斷言」的東西,檢查的JUnit出它只是意味着「這是真/假」。):

@Test 
public void testCrazy() 
{   
    Object firstObject = new Object(); 
    // now I have a reference on the stack (firstObject) that points to some memory 
    // location on the heap that holds some bytes representing an Object instance 
    Object secondObject = new Object(); 
    // now I have another reference pointing to a DIFFERENT location on the 
    // heap 
    boolean equalReferences = (firstObject == secondObject); 
    // equalReferences is expected to be false 
    assertFalse(equalReferences); 

    // look, I make the first reference point to the locations held by the 
    // second one (tha is what = does if applied to references) 
    firstObject = secondObject; 
    // now the 2 references are expected to pass the equality operator test 
    assertTrue(firstObject == secondObject); 

    // what if I override equals in a completely nonsense way? 
    firstObject = new Object(){ 
     @Override 
     public boolean equals(Object obj) 
     { 
      // no matter what, it always returns false. 
      // does it make sense? Probably not in our common sense, but the 
      // compiler won't complain 
      return false; 
     } 
    }; 

    secondObject = firstObject; 
    // now they do point to same same memory location, in fact 
    assertTrue(secondObject == firstObject); 

    // but if I call the overriden equals method: 
    assertFalse(firstObject.equals(secondObject)); 

    // it is still failing even if I call equals on firstObject itself: 
    assertFalse(firstObject.equals(firstObject)); 
}