Domanda

class D {
    public static void main(String args[]) {
        Integer b2=128;
        Integer b3=128;
        System.out.println(b2==b3);
    }
}

Output:

false

class D {
    public static void main(String args[]) {
        Integer b2=127;
        Integer b3=127;
        System.out.println(b2==b3);
    }
}

Output:

true

Nota: I numeri tra -128 e 127 sono vere

.
È stato utile?

Soluzione

Quando si compila un numero letterale in Java e assegnarlo a un numero intero (I capitale) il compilatore emette:

Integer b2 =Integer.valueOf(127)

Questa riga di codice viene generato anche quando si utilizza autoboxing.

valueOf è implementata in modo tale che alcuni numeri sono "riuniti", e restituisce la stessa istanza per valori inferiori a 128.

Dal codice sorgente di Java 1.6, la linea 621:

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

Il valore del high può essere configurato per un altro valore, con la proprietà di sistema.

  

-Djava.lang.Integer.IntegerCache.high = 999

Se si esegue il programma con quella proprietà di sistema, il risultato sarà vero!

L'ovvia conclusione: mai fare affidamento su due riferimenti sono identici, li confronta sempre con metodo .equals()

.

Così b2.equals(b3) stamperà vero per tutti i valori logicamente uguali di B2, B3.

Si noti che la cache Integer non è lì per motivi di prestazioni, ma piuttosto di conformarsi al JLS, sezione 5.1.7 ; identità oggetto deve essere dato per i valori da -128 a 127 compreso.

Integer # valueOf (int) documenta anche questo comportamento:

  

questo metodo rischia di produrre significativamente migliore spazio e nel tempo le prestazioni mettendo in cache i valori frequentemente richiesti. Questo metodo sarà sempre in cache i valori nella gamma da -128 a 127, comprensivo, e può memorizzare nella cache altri valori al di fuori di questo intervallo.

Altri suggerimenti

Autoboxing memorizza nella cache da -128 a 127. Questo è specificato nella JLS ( 5.1.7 ).

  

Se il valore p di essere inscatolato è vero, falso, un byte, un char nel campo \ u0000 a \ u007F, o un numero di int o cortocircuito tra -128 e   127, poi lasciate r1 e r2 essere i risultati di qualsiasi due conversioni boxe   di p. E 'sempre il caso che r1 == r2.

Una semplice regola da ricordare quando si tratta di oggetti è - uso .equals se si desidera controllare se i due oggetti sono "uguali", l'uso == quando si vuole vedere se puntano alla stessa istanza

.

Utilizzare tipi di dati primitivi, int, produrrebbe vero in entrambi i casi, i risultati attesi.

Tuttavia, dal momento che si sta utilizzando Integer oggetti l'operatore == ha un significato diverso.

Nel contesto di oggetti, == controlla se le variabili si riferiscono allo stesso riferimento all'oggetto.

Per confrontare il valore degli oggetti è necessario utilizzare l'equals (metodo) Per es.

 b2.equals(b1)

che indicano se b2 è inferiore b1, maggiore o uguale a (controllare le API per i dettagli)

E 'l'ottimizzazione della memoria in Java correlati.

  

Per salvare sulla memoria, Java 'riutilizza' tutti gli oggetti wrapper valori la cui   rientrano nei seguenti intervalli:

     

Tutti i valori booleani (vero e falso)

     

Tutti i valori di byte

     

Tutti i valori di carattere da \ u0000 a \ u007F (cioè da 0 a 127 in decimale)

     

Tutti i valori brevi e intero da -128 a 127.

Dai un'occhiata al Integer.java, se il valore è compreso tra -128 e 127, userà la piscina nella cache, in modo da (Integer) 1 == (Integer) 1 mentre (Integer) 222 != (Integer) 222

 /**
 * Returns an {@code Integer} instance representing the specified
 * {@code int} value.  If a new {@code Integer} instance is not
 * required, this method should generally be used in preference to
 * the constructor {@link #Integer(int)}, as this method is likely
 * to yield significantly better space and time performance by
 * caching frequently requested values.
 *
 * This method will always cache values in the range -128 to 127,
 * inclusive, and may cache other values outside of this range.
 *
 * @param  i an {@code int} value.
 * @return an {@code Integer} instance representing {@code i}.
 * @since  1.5
 */
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);
}       

ho scritto quanto segue come questo problema non è solo specifico per intero. La mia conclusione è che il più delle volte, se si utilizza l'API in modo non corretto, si vede davanzale comportamento non corretto. Utilizzare correttamente e si dovrebbe vedere il comportamento corretto:

public static void main (String[] args) {
    Byte b1=127;
    Byte b2=127;

    Short s1=127; //incorrect should use Byte
    Short s2=127; //incorrect should use Byte
    Short s3=128;
    Short s4=128;

    Integer i1=127; //incorrect should use Byte
    Integer i2=127; //incorrect should use Byte
    Integer i3=128;
    Integer i4=128;

    Integer i5=32767; //incorrect should use Short
    Integer i6=32767; //incorrect should use Short

    Long l1=127L;           //incorrect should use Byte
    Long l2=127L;           //incorrect should use Byte
    Long l3=13267L;         //incorrect should use Short
    Long l4=32767L;         //incorrect should use Short
    Long l5=2147483647L;    //incorrect should use Integer 
    Long l6=2147483647L;    //incorrect should use Integer
    Long l7=2147483648L;
    Long l8=2147483648L;

    System.out.print(b1==b2); //true  (incorrect) Used API correctly
    System.out.print(s1==s2); //true  (incorrect) Used API incorrectly
    System.out.print(i1==i2); //true  (incorrect) Used API incorrectly
    System.out.print(l1==l2); //true  (incorrect) Used API incorrectly

    System.out.print(s3==s4); //false (correct) Used API correctly
    System.out.print(i3==i4); //false (correct) Used API correctly
    System.out.print(i5==i6); //false (correct) Used API correctly
    System.out.print(l3==l4); //false (correct) Used API correctly
    System.out.print(l7==l8); //false (correct) Used API correctly
    System.out.print(l5==l6); //false (correct) Used API incorrectly

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top