2012-03-22 13 views
11

Il seguente codice mi è sembrato molto confuso poiché forniva due output diversi. Il codice è stato testato su jdk 1.7.Come funzionano gli operatori! = E == su Integers in Java?

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"); 
    } 
} 

} 

uscita:

[ver1 uscita]
Diversi oggetti
Significativamente uguali.

[ver2 uscita]
oggetto uguale
Significativamente pari

Perché == e! = Test produce risultati diversi per ver1() e ver2() per lo stesso numero molto inferiore al numero intero. MAX_VALUE? Si può concludere che il controllo == di numeri superiori a 127 (per classi wrapper come Integer come mostrato nel codice) è totalmente inutile?

+3

Questo perché il meccanismo di autoboxing memorizza nella cache e riutilizza lo stesso oggetto per i valori nell'intervallo -128 - 127. Questo è un duplicato di una domanda precedente. – aioobe

+0

@quixoto: vedere la mia risposta di modifica :) – BoltClock

+1

http://stackoverflow.com/questions/1700081/why-does-128-128-return-false-but-127-127-return-true-when-converting-to -integ –

risposta

10

I numeri interi sono memorizzati nella cache per valori compresi tra -128 e 127, pertanto Integer i = 127 restituirà sempre lo stesso riferimento. Integer j = 128 non necessariamente lo farà. Sarà quindi necessario utilizzare equals per verificare l'uguaglianza del sottostante int.

Questo fa parte del Java Language Specification:

Se il valore p essere inscatolato è vero, falso, un byte, o un char nell'intervallo \ u0000 a \ u007F, o un numero int o corto tra -128 e 127 (inclusi), quindi lascia che r1 e r2 siano i risultati di due conversioni di boxing di p. È sempre il caso che r1 == r2.

Ma 2 chiamate alla Integer j = 128 possono restituire lo stesso riferimento (non garantito):

Meno implementazioni memoria limitata potrebbe, per esempio, cache tutti i valori char e corte, nonché int e long valori nell'intervallo da -32K a +32K.

+0

Tuttavia, la funzione di costruzione non utilizza la memorizzazione nella cache. Prova: System.out.println (new Integer (2) == new Integer (2)) – fgb

+1

'new Integer (127)' non restituirà mai lo stesso riferimento. In effetti, garantisce di creare sempre un nuovo oggetto. Ma quando si usa il box automatico come in "Integer i = 127;" allora viene usata la cache. Btw il bordo superiore 127 non è fisso ma un minimo. Può essere configurato su un valore maggiore ma non inferiore. –

4

Poiché i piccoli interi sono internati in Java e si sono tentati i numeri su lati diversi del limite di "piccolezza".

+0

@downvoter, ti piacerebbe elaborare il tuo voto? – dasblinkenlight

0

Java inserisce nella cache interi da -128 a 127 Ecco perché gli oggetti SONO uguali.

0

Penso che gli operatori == e! = Quando si occupano di primitive funzioneranno come si stanno attualmente usando, ma con gli oggetti (intero o int) si vorrà eseguire test con il metodo .equals().

Non sono sicuro su questo, ma con gli oggetti il ​​== testerà se un oggetto è lo stesso oggetto o meno, mentre .equals() eseguirà il test che quei due oggetti contengano l'equivalenza nel valore (o il metodo dovrà essere creato/sovrascritto) per oggetti personalizzati.

3

Esiste una cache di oggetti Integer da -128 e fino a 127 per impostazione predefinita. Il bordo superiore può essere configurato.Il bordo della cache superiore può essere controllato opzione VM -XX:AutoBoxCacheMax=<size>

Si utilizza questa cache quando si utilizza il modulo:

Integer i1 = 127; 

o

Integer i1 = Integer.valueOf(127); 

Ma quando si utilizza

Integer i1 = new Integer(127); 

quindi è garantito per ottenere un nuovo oggetto non collegato. In quest'ultimo caso entrambe le versioni mostrano gli stessi risultati. Usando le versioni memorizzate nella cache possono essere diverse.

+0

Bello sapere. Per favore, non farlo in produzione. – atamanroman

Problemi correlati