2013-10-02 12 views
5

Ho questa domanda intervista:Integer specifico (Java Core)

public Integer v1 = 127; 
public Integer v2 = 127; 
public Integer v3 = 513; 
public Integer v4 = 513; 

public void operatorEquals(){ 
    if (v1==v2) 
     System.out.println("v1 == v2"); 
    else throw new RuntimeException("v1 != v2"); 
    if (v3==v4) 
     System.out.println("v3 == v4"); 
    else throw new RuntimeException("v3 != v4"); 
} 

**Result**: java.lang.RuntimeException: **v3 != v4** 

si può spiegare: perché? Non ho suggerimenti.

risposta

10

Java Integer oggetti vengono memorizzati nella cache fino a 127, ma non sopra.

L'effetto di questo è molto simile a come i String interning opere, in modo che tutti Integer oggetti con valori nell'intervallo [-128; 127] sono le stesse casi anche - restituendo vero con controllo di uguaglianza referenziale troppo, (es. ==), non solo usando .equals().

EDIT da Arnaud Denoyelle

Da Integer.java:

public static Integer valueOf(int i) { 
    assert IntegerCache.high >= 127; 
    if (i >= IntegerCache.low && i <= IntegerCache.high) 
     return IntegerCache.cache[i + (-IntegerCache.low)]; 
    return new Integer(i); 
} 
+1

Non sospirerei _that_ much. –

+4

Puoi spiegare più dettagliato ...? – user2171669

+1

Ho modificato per mostrare il codice di 'Intero # valoreOf()'. Come puoi vedere, tra IntegerCache.low (-128) e IntegerCache.high (+127), in realtà non crei un nuovo numero intero. –

4

Questo è il comportamento definito per Java quando Autoboxing. Controllare il codice Java Language Specification section. Leggi anche la sezione di discussione. Il seguente paragrafo è tratto dal disciplinare:

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

Idealmente, la boxing di un dato valore primitivo p, darebbe sempre un riferimento identico a . In pratica, questo potrebbe non essere fattibile usando le tecniche di implementazione esistenti . Le regole di cui sopra sono un pragmatico compromesso . La clausola finale sopra richiede che determinati valori comuni siano sempre racchiusi in oggetti indistinguibili. L'implementazione può memorizzare nella cache , pigramente o con impazienza. Per altri valori, questa formulazione non consente alcuna ipotesi sull'identità dei valori in box su parte del programmatore. Ciò consentirebbe (ma non richiederà) la condivisione di alcuni o tutti questi riferimenti.

Ciò garantisce che, nella maggior parte dei casi, il comportamento sarà il desiderato, senza imporre una penalità di prestazioni eccessive, in particolare su dispositivi di piccole dimensioni. Meno implementazioni a memoria limitata potrebbero, per esempio , memorizzare tutti i valori char e short, così come i valori int e long nell'intervallo da -32K a +32K.

Per interi, quelli compresi tra -128 e 127 (inclusi) oggetti Inbox automatici restituiscono true per il controllo ==. Si dice che questi numeri interi siano memorizzati nella cache e in un pool costante. Ma se fai semplicemente new Integer(int) gli oggetti creati saranno sempre diversi.