2011-04-18 76 views
3

發現在我的筆記以下,但我無法理解它:淺淺和深深的平等有什麼區別?這如何應用於緩存?

原始類型的包裝類實現緩存值的數量有限 。
這保證了有限數量的深度相等的包裝對象 也很淺: 如果o1.equals(o2)然後o1 == o2。例如
一般來說,這並不總是奏效。
例如,新的整數(666)==新的整數(666)
可能不成立。
緩存的原因是它節省了內存。
一般緩存適用於「小」原始值。

我不明白這是什麼意思,或深層(.equals())和淺(==)等號之間有什麼區別。我在實踐中知道,.equals必須用於對象和==爲整數值,但實際推理暗示了我。

我假設名稱淺可能只是檢查兩個值是相同的類型和名稱,深入檢查這兩個變量指向同一個對象?雖然我看不出緩存如何發揮作用,或者爲什麼它會有用。

+0

那麼,你的筆記是完全錯誤的。 '新的整數(0)==新的整數(0)'將永遠不會,永遠,*永遠***爲真,也不會'新的整數(666)==新的整數(666)'。我建議你請教授澄清他的意思,因爲如果他在考試中期望這一點,他對Java就知之甚少。 – 2011-04-18 13:32:39

回答

5

當你做==你正在比較相等的參考。這意味着你在說「兩個對象的內存地址是相同的嗎?」

當你做.equals()你正在比較對象本身的平等。這意味着你說「這兩個對象認爲自己是平等的嗎?」

給出的例子很差。 對於這些由JLS強制執行的數字所做的唯一緩存是.valueOf()方法。構造函數沒有被緩存。

此外,JLS僅指定您必須緩存的最小 [-128:127]。 JVM實現可能會緩存更多,如果他們選擇的話。這意味着Integer.valueOf(500) == Integer.valueOf(500)可能在某些機器上爲false,但在其他機器上爲true

class biziclop { 

    public static void main(String[] args) { 
     System.out.println(new Integer(5) == new Integer(5)); 
     System.out.println(new Integer(500) == new Integer(500)); 

     System.out.println(Integer.valueOf(5) == Integer.valueOf(5)); 
     System.out.println(Integer.valueOf(500) == Integer.valueOf(500)); 
    } 
} 

結果:(!評論是寶石)

C:\Documents and Settings\glow\My Documents>java biziclop 
false 
false 
true 
false 

C:\Documents and Settings\glow\My Documents> 

看到更詳細的答案在這裏:Why do people still use primitive types in Java?

+0

嗨, 如何輸出 System.out.println(Integer.valueOf(5)== Integer.valueOf(5)); System.out.println(Integer.valueOf(500)== Integer.valueOf(500)); 不同?? – 2015-09-21 22:15:32

+1

這就是答案的全部觀點:'5'足夠小,JVM可以緩存它,而'500'則不是。儘管可能是這樣,但在一些罕見的機器上它可能是相同的(都是這樣),但在大多數機器上,'5'將被cahced並因此返回相同的Integer對象,而'500'不會如此'valueOf'將創建'新的Integer's。 – corsiKa 2015-09-21 22:17:45

+0

Ohk,現在我明白了 – 2015-09-21 22:20:52

1

equals()方法測試兩個對象是否在本質上是相同的,但它可以爲兩個不同的對象返回true;即兩個不同的回形針是「等於」。引用類型的「==」測試兩個引用是否引用同一個對象 - 即,一個回形針僅針對其自身。 ==測試身份,其中equals測試等同

你可能有兩個不同的Integer對象,其中0(它們是equals());緩存意味着保存對象並在可能時重新使用它們。

0

你所說的「淺等於」是身份:如果兩個引用(即對象)是完全相同的實例,則它們是相同的。如果您知道其他語言中的指針,您可以將標識與指針相等進行比較。

你叫什麼?「深平等」是平等:兩個對象ab都是平等的,如果a.equals(b)回報true(希望反之亦然)。平等的正確性很大程度上取決於實施方法equals。有關更多詳細信息,請參閱Object課程的Javadoc。

2

第一關:new Integer(0) == new Integer(0)從未評估爲true,爲new總是創建一個新的對象,迴避任何可能存在的自動裝箱緩存機制。

您可能聽說過的是自動裝箱(即必要時將原始值自動轉換爲各自的包裝類)。自動裝箱使用的機制也可以使用包裝類valueOf()方法訪問。換句話說:自動裝箱intInteger的工作方式幾乎與呼叫Integer.valueOf(int)的工作方式相同。

Integer.valueOf(0) == Integer.valueOf(0)評估到true,因爲共同的值(即具有低絕對值的值)被緩存。當您連續撥打valueOf(0)兩次時,您將收到相同的Integer對象。對於更高的值(例如666),這不一定是正確的。

5

嗯,其實淺/深剝離是從== /等於解剖不同:

  1. ==比較的對象的身份,那就是你檢查 操作數是否實際上 相同的(兩個引用到相同的內存區域), 而equals比較對象 等價,即「邏輯」值爲 的兩個,可能不相同的對象是 的對象,是相同的。如果兩個 對象

    a == b 
    

    那麼這是真的,

    a.equals(b) // if a != null 
    

    ,但相反的是不是在所有情況下 真。

  2. 淺/深分別有道理 只適用於equals比較。 你只比較 兩個對象 的即時內容淺手段發現他們是否「等於」在你 感,而直到你需要 比較您 比較的對象的內容 遞歸深的方法是原始的領域。如果 您將equals對象的方法定義爲 equals對這些對象的實例字段的調用順序,則使用深度比較。如果 您使用== 運算符來定義equals運算符來比較化合物類型, 如字符串,那麼您使用淺比較 - 並且這在Java中不正確。

所有這些的士氣是,您絕不能使用==來比較兩個複合對象,除非只有它們相同時才認爲它們相等。

+0

你說的是真的,但看起來好像講師用「淺」來表示參考身份,而「深」來表示等同。邏輯肯定是合理的。 – 2011-04-18 15:31:33