
Jaki będzie efekt działania poniższego kodu?
public class Main { public static void main(String[] args) { String janusz = "Janusz"; String person = new String(janusz); String name = "Janusz" + ""; String januszUppercase = new String("JANUSZ"); System.out.println(janusz == person); System.out.println(name == person); System.out.println(janusz == name); System.out.println(janusz.equals(name)); System.out.println(januszUppercase.equalsIgnoreCase(name)); System.out.println(januszUppercase == janusz); } }
Po uruchomieniu takiego kodu otrzymamy w konsoli następujący rezultat:
false false true true true false
Czemu tak się dzieje? Czemu pomimo porównywania tych samych wartości otrzymujemy false?
Dzieje się tak, ponieważ w Javie istnieje taki byt jak String Pool. Wszystkie Stringi stworzone przy użyciu cudzysłowów są zapisywane w String Pool i są one przechowywane w dokładnie jednym egzemplarzu. Jeśli dodajemy nowy ciąg znaków i taki już istnieje do String Pool to nie zostanie on dodany tylko automatycznie otrzymamy adres już istniejącego Stringa w String Pool.
Taki mechanizm pozwala zaoszczędzić sporo pamięci w aplikacji – dużo obiektów typu String po prostu wskazuje na ten sam obszar pamięci. Jeśli oba wskazują na ten sam obszar w pamięci to operator == zwróci nam prawdę, ponieważ sprawdza on tylko referencję obiektów.
Do sprawdzania realnej równości obiektów – na podstawie ich zawartości – posłuży Ci metoda equals.
Jeśli chcesz dowiedzieć się więcej na temat porównywania obiektów w Javie zerknij na ten artykuł.