Czemu czasami porównanie obiektu typu Integer dzięki "==" działa?

pater.dev 5 lat temu

Ciężko na początku swojej nauki zrozumieć czemu porównywanie dzięki operatora == jest nie do końca poprawne. Pytanie dotyczące porównywania Stringa na rozmowa rekrutacyjnych pojawia się równie często co pytanie o to czym jest interfejs.

Staramy wyrobić sobie taką intuicję, iż o ile nie są to typy prymitywne (int, boolean..) to najlepszym rozwiązaniem będzie porównywanie obiektów dzięki specjalnych metod – equals czy compareTo. Ale okazuje się, iż czasami jednak to „naiwne” porównanie obiektów dzięki operatora == działa i wtedy warto się zastanowić – czemu?

Sprawdźmy co siedzi w źródle

Zacznijmy może od przypomnienia, iż konstrukcja:

Integer a = 128;

Jest przez kompilator konwertowana do:

Integer a = Integer.valueOf(128);

Jest to dosyć ważne, bo teraz wiemy gdzie szukać – zobaczmy co się kryje w metodzie valueOf:

Implementacja metody valueOf(int i)

Okazuje się, iż valueOf robi coś więcej niż tylko opakowanie naszego inta w obiekt Integer. To też poniekąd tłumaczy sytuację, która widzimy tutaj:

Nie zawsze Integer 127 == Integer 127

Wracając do implementacji valueOf – o ile nasza wartość znajduje się we właściwym przedziale (domyślnie jest to: [-128, 127]) to zwrócona zostanie wartość z cache znajdującego się w statycznej klasie IntegerCache. Ten przedział możemy bez problemu zmienić ustawiając w konfiguracji VM zmienną -XX:AutoBoxCacheMax=rozmiar

Na zakończenie.. W jednym z projektów przy którym miałem okazję pracować jakiś czas temu, znalazłem sporo takich miejsc w których obiekty typu Integer porównywane są dzięki ==. W momencie gdy poruszyłem ten temat, przedstawiając swoje obawy, dostałem odpowiedź – Przecież to działa, bo przy porównywaniu poprzez == jest unboxing. I rzeczywiście to działało, ale powód był inny – te liczby, które zwykle pod tymi zmiennymi się kryły, były po prostu bardzo małe.

Idź do oryginalnego materiału