Autoboxing - tajemnice

0

Witam,
wynikiem odpalenia kodu

 
class Main {
    static public void main(String[] args) {    
                Integer a = new Integer(1);
                Integer b = new Integer(1);
 
                if(a != b)
                    System.out.println("qwerty");
                
                
        }
}

jest "qwerty", a kodu

 
class Main {
    static public void main(String[] args) {    
                Integer a = 1;
                Integer b = 1;
   
                if(a != b)
                    System.out.println("qwerty");
                
                
        }
}

nic.

Czemu w drugim przypadku a i b wskazują na tą samą zmienną ? Nie tworzy się nowy obiekt ? Jest jakieś wytłumaczenie tego zjawiska ?

2

W drugim przypadku wygenerowany bytecode ma pewnie postac wywolania Integer.valueOf(1) dwa razy, a tam jest cachowanie (zdaje sie -127 do 128). Nie jestem pewien, ale wydaje mi sie ze to jest specyficzne dla Oracle Java, a w innych tak nie musi byc (prosze mnie poprawic jak ktos wie lepiej!).
Jawne wolanie konstruktora zawsze daje nowa, nie cachowane instancje, dlatego nie moga one sobie byc rowne.
Do tego dochodzi fakt ze w porownaniu typow referencyjnych (a takimi sa Integery) porownujesz nie wartosc lecz referencje do obiektow.

0

W pierwszym porownujesz referencje do obiektow a w drugim ich wartosc, ktora jest taka sama.

0

@mućka ma tutaj sluszność. Oraclowa implementacja Javy (i pewnie nie tylko) ma dla autoboxowych klas cache i Integer faktycznie przechowuje sobie liczby z pewnego zakresu i jeśli tworzysz Integer przez valueOf() to dostaniesz obiekt z cache, o ile mieści się w zakresie. Podobnie jest z internalizowanymi Stringami na przykład.
Porównanie przez == i != porównuje referencje do obiektów, więc zwraca true tylko jeśli porównujesz ten sam obiekt.

edit: implementacja openjdk:

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

Dasz plusika? ;d

Aby zakonczyc temat, tutaj cytat z dokumentacji metody Integer.valueOf():

Returns an Integer instance representing the specified int value. If a new Integer instance is not required, this method should generally be used in preference to the constructor 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.

Czyli - -128 do 127 jest zawsze cachowane, niezaleznie od implementacji JVM, ale moze byc cachowane wiecej.

1 użytkowników online, w tym zalogowanych: 0, gości: 1