Lipiec 17, 2019

Porównywanie Stringów

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ł.