Frage

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

Ausgabe:

false

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

Ausgabe:

true

Hinweis: Die Zahlen zwischen -128 und 127 sind true

.
War es hilfreich?

Lösung

Wenn Sie eine Nummer kompilieren wörtliche in Java und Zuweisen zu einem Integer (Kapital I) der Compiler gibt:

Integer b2 =Integer.valueOf(127)

Diese Codezeile wird auch erzeugt, wenn Sie Autoboxing verwenden.

valueOf ist so implementiert, dass bestimmte Zahlen „gepoolt“ werden, und es gibt die gleiche Instanz für Werte kleiner als 128.

Von dem Java-1.6-Quellcode, Zeile 621:

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

Der Wert von high kann auf einem anderen Wert konfiguriert werden, mit der Systemeigenschaft.

  

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

Wenn Sie Ihr Programm mit der Systemeigenschaft laufen, gibt er wahr!

Die offensichtliche Schlussfolgerung: verlassen nie auf zwei Referenzen identisch sind, vergleichen sie immer mit .equals() Methode

.

So b2.equals(b3) für alle logisch gleichen Werte von b2 wahr drucken, b3.

Beachten Sie, dass Integer Cache dort nicht aus Leistungsgründen, sondern vielmehr auf die JLS, Abschnitt 5.1.7 ; Objektidentität muss für Werte von -128 bis 127 einschließlich gegeben werden.

Integer # valueOf (int) auch dieses Verhalten dokumentiert:

  

Diese Methode ist wahrscheinlich durch Caching häufig geforderte Werte deutlich bessere Raum- und Zeitleistung erhalten. Diese Methode wird immer Cache-Werte im Bereich von -128 bis 127, und können andere Werte zwischenzuspeichern außerhalb dieses Bereichs.

Andere Tipps

Autoboxing-Caches -128 bis 127 in der JLS Dies ist angegeben ( 5.1.7 ).

  

Wenn der Wert p eingerahmt wird, ist wahr, falsch, ein Byte, ein Zeichen im Bereich \ u0000 bis \ u007f oder eine int oder Kurz Zahl zwischen -128 und   127, dann lassen Sie R1 und R2 werden die Ergebnisse von zwei Boxen Conversions   p. Es ist immer der Fall, dass r 1 == r2.

Eine einfache Regel zu erinnern, wenn mit Objekten zu tun ist - Verwendung .equals, wenn Sie, wenn die beiden Objekte prüfen wollen, „gleich“ sind, verwenden == wenn Sie sehen wollen, wenn sie auf die gleiche Instanz zeigen

.

Mit primitiven Datentypen, Ints, in beiden Fällen erzeugen würde wahr, die erwartete Ausgabe.

Da Sie Integer verwenden Objekte der Operator == eine andere Bedeutung hat.

Im Rahmen von Objekten, == prüft, ob die Variablen auf die gleiche Objekt Referenz beziehen.

Um den Wert der Objekte vergleichen Sie die Gleichen verwenden soll () -Methode Z.

 b2.equals(b1)

, die zeigen an, ob b2 kleiner als b1, größer oder gleich (überprüfen Sie die API für weitere Details)

Es ist die Speicheroptimierung in Java zusammen.

  

auf Speicher zu speichern, Java ‚Wiederverwendungsmöglichkeiten‘ alle Wrapper-Objekte, deren Werte   fallen in den folgenden Bereichen:

     

Alle Boolesche Werte (wahr und falsch)

     

Alle Byte-Werte

     

Alle Zeichen Werte von \ u0000 \ u007f (d.h. 0 bis 127 dezimal)

     

Alle Short und Integer-Werte von -128 bis 127.

Haben Sie einen Blick auf die Integer.java, wenn der Wert zwischen -128 und 127 ist, wird die im Cache-Pool nutzen, so (Integer) 1 == (Integer) 1 während (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);
}       

Ich habe den folgenden wie dieses Problem nicht nur spezifisch für Integer ist. Meine Schlussfolgerung ist, dass mehr als oft nicht, wenn Sie die API nicht ordnungsgemäß verwenden, Schweller Sie falsches Verhalten sehen. Verwenden Sie es richtig, und Sie sollten das richtige Verhalten sehen:

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

}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top