Kategorie szkoleń | Egzaminy | Kontakt
  • 2
  • 3
  • 137
public class Test {
    public static void main(String[] args) {
        Integer i = 10, j = 10, k = 1000, l = 1000;
       
        System.out.println(i == j);
        System.out.println(k == l);
       
    }
}
Wojciech_Sobczak
  • Zapytał
  • @ Wojciech_Sobczak | 26.11.2014
    • 7
    • 0
    • 3

Odpowiedzi (2)

  • 8

Takie zachowanie bierze się z faktu istnienia mechanizmu Cache w celu optymalizacji wydajności  np. pętle "for" dla niewielkich ilości iteracji, proste obliczenia itp. Dla małych liczb całkowitych przechowywanych w Integer, Short, a nawet Long  (odpakowana wartość musi się mieścić w 8 bitach ze znakiem), czyli dla zakresu od -128 do +127, wartości te są trzymane właśnie w Cache, i w wyniku optymizacji tak są ustawiane referencje, aby wskazywały na ten sam obiekt w pamięci.

 

Operator == w przykładzie:

 

Integer i = 10, j = 10;
System.out.println(i == j);

 

jest w istocie porównaniem referencji do dwóch obiektów typu Integer - w tym przypadku, dzięki optymizacji, te referencje są równe. Operator nie porównuje tu wartości "zaszytej" dzięki mechanizmowi autoboxingu, w środku Integera. 

Na marginesie, używając porównania typów prostych np.:

 

int i = 1000, j = 1000;
System.out.println(i==j);

 

zawsze dostaniemy wartość true, ponieważ dla typów prostych (int, short, long) operator == porównuje wartość zmiennej.

Możesz też zerknąć do implementacji klasy Integer, a szczególnie do kodu metody valueOf(...) i klasy zagnieżdżonej IntegerCache - tam widać, że klasa IntegerCache zawiera tablicę Integerów.

 

Cytuję komentarz:

 

Cache to support the object identity semantics of autoboxing for values between
-128 and 127 (inclusive) as required by JLS.
Maciej_Krauze
  • Odpowiedział
  • @ Maciej_Krauze | 26.11.2014
    • lider
    • laureat
    • 45
    • 16
    • 58
  • 1

Odbiegając trochę od tematu, warto zauważyć, że takich optymalizacji jest w Javie więcej. Przykładem może być klasa java.lang.String. Podobnie jak klasy opakowujące typy proste jest ona niezmienna (immutable). Dzięki temu obiekty tworzone poprzez literały są odkładane w puli i przed utworzeniem nowego obiektu, najpierw sprawdzane jest, czy nie ma go w puli. W takim przypadku tworzona jest tylko nowa referencja wskazująca ten sam obiekt. Stąd porównanie:

 

String s1 = "abc";
String s2 = "abc";
System.out.println(s1  == s2);

 

zwróci wartość true.

Inaczej sprawa przedstawia się, gdy użyjemy jawnie konstruktora. Wtedy:

 

String s1 = "abc";
String s2 = new String("abc");
System.out.println(s1 == s2);

 

porównanie referencji zwróci wartość false (zaś metoda equals - wartość true).

  • Odpowiedział
  • @ | 03.02.2015
  • TRENER MODERATOR ALTKOM AKADEMII