2012-03-22 68 views
11

下面的代碼似乎讓我很困惑,因爲它提供了兩個不同的輸出。代碼在jdk 1.7上進行了測試。How!=和==運算符在Java中的Integers上工作嗎?

public class NotEq { 

public static void main(String[] args) { 

    ver1(); 
    System.out.println(); 
    ver2(); 
} 

public static void ver1() { 
    Integer a = 128; 
    Integer b = 128; 

    if (a == b) { 
     System.out.println("Equal Object"); 
    } 

    if (a != b) { 
     System.out.println("Different objects"); 
    } 

    if (a.equals(b)) { 
     System.out.println("Meaningfully equal."); 
    } 
} 

public static void ver2() { 
    Integer i1 = 127; 
    Integer i2 = 127; 
    if (i1 == i2) { 
     System.out.println("Equal Object"); 
    } 

    if (i1 != i2){ 
     System.out.println("Different objects"); 
    } 
    if (i1.equals(i2)){ 
     System.out.println("Meaningfully equal"); 
    } 
} 

} 

輸出:

[VER1輸出]
不同的對象
有意義相等。

[VER2輸出]
平等對象
有意義等於

爲什麼==和!=測試產生用於VER1()和VER2()爲相同數目大於整數小得多不同的結果。 MAX_VALUE?是否可以得出結論:==檢查大於127的數字(如代碼中所示的Integer等包裝類)是否完全浪費時間?

+3

這是因爲自動裝箱機制緩存和重新使用範圍-128 - 127中的值的同一對象。這是上一個問題的重複。 – aioobe 2012-03-22 14:16:36

+0

@quixoto:看我的編輯回覆:) – BoltClock 2012-03-22 14:41:54

+1

http://stackoverflow.com/questions/1700081/why-does-128-128-return-false-but-127-127-return-true-when-converting-to -integ – 2016-02-17 13:16:56

回答

10

整數緩存的值介於-128和127之間,因此Integer i = 127將始終返回相同的引用。 Integer j = 128不一定會這樣做。然後您將需要使用equals來測試相關的int的平等。

這是Java Language Specification的一部分:

如果被裝箱值p爲真,假,字節,或在範圍\ u0000的一個char到\ u007f之間,或在一個int或短號碼-128和127(含),那麼令r1和r2是p的任何兩次裝箱轉換的結果。 r1 == r2總是如此。

但2調用Integer j = 128可能返回相同的附圖(不保證):

更少的內存限制的實施方式中可能,例如,高速緩存的所有char和短的值,以及int和長值在-32K到+ 32K範圍內。

+0

雖然構造函數不使用緩存。嘗試:System.out.println(new Integer(2)== new Integer(2)) – fgb 2012-03-22 14:25:04

+1

'new Integer(127)'永遠不會返回相同的引用。實際上,它確保始終創建一個新對象。但是當像「Integer i = 127;」那樣使用自動裝箱時,則使用緩存。順便說一句,上邊界127不是固定的,而是最小的。它可以配置爲更大的值,但不能更低。 – 2012-03-22 14:27:30

4

由於小整數在Java中被執行,並且您嘗試了「小」限制的不同側上的數字。

+0

@downvoter,你願意詳細說明你的投票嗎? – dasblinkenlight 2012-03-22 14:41:22

0

Java緩存從-128到127的整數這就是爲什麼對象是相同的。

0

我認爲==和!=運算符在處理基元時會如何使用它們,但對於對象(整數與int),您將需要使用.equals()方法執行測試。如果一個對象是相同的對象,而.equals()將執行測試,這兩個對象在值中包含等價(或方法將需要創建/重寫)自定義對象。

3

默認情況下存在一個從-128到127的Integer對象緩存。上邊框可以配置。上高速緩存的邊界可以通過VM選項控制-XX:AutoBoxCacheMax=<size>

您使用此緩存,當您使用以下形式:

Integer i1 = 127; 

Integer i1 = Integer.valueOf(127); 

但是當你使用

Integer i1 = new Integer(127); 

那麼你保證會得到一個新的未緩存的對象。在後一種情況下,兩個版本都打印出相同的結果。使用緩存版本他們可能會有所不同。

+0

很高興知道。請不要在生產中這樣做。 – atamanroman 2015-03-02 11:52:25