assertEquals
używa equals
metody do porównania. Istnieje inne stwierdzenie assertSame
, które wykorzystuje ==
operator.
Aby zrozumieć, dlaczego ==
nie należy używać z łańcuchami, musisz zrozumieć, co ==
robi: wykonuje kontrolę tożsamości. Oznacza to, że a == b
sprawdza, czy a
i b
odnoszą się do tego samego obiektu . Jest wbudowany w język i jego zachowanie nie może być zmienione przez różne klasy. Z equals
drugiej strony metoda może być nadpisana przez klasy. Podczas gdy jego domyślnym zachowaniem (w Object
klasie) jest sprawdzanie tożsamości za pomocą ==
operatora, wiele klas, w tym String
, zastępuje go, aby zamiast tego sprawdzać „równoważność”. W przypadku String
, gdyby zamiast sprawdzania a
i b
odnoszą się do tego samego obiektu,a.equals(b)
sprawdza, czy obiekty, do których się odnoszą, są ciągami znaków zawierającymi dokładnie takie same znaki.
Czas analogii: wyobraź sobie, że każdy String
przedmiot jest kawałkiem papieru z czymś na nim napisanym. Powiedzmy, że mam na sobie dwa kawałki papieru z napisem „Foo”, a drugi z napisem „Bar”. Jeśli wezmę pierwsze dwa kawałki papieru i ==
użyję ich do porównania, wróci, false
ponieważ zasadniczo pyta: „czy to ten sam kawałek papieru?”. Nie musi nawet patrzeć na to, co napisano na papierze. Fakt, że daję mu dwa kawałki papieru (zamiast tego samego dwa razy) oznacza, że wróci false
. Jeśli equals
jednak użyję, equals
metoda odczyta dwa kawałki papieru i zobaczy, że mówią to samo („Foo”), więc wróci true
.
Bit, który staje się mylący z ciągami, polega na tym, że Java ma koncepcję „internowania” ciągów i jest to (skutecznie) automatycznie wykonywane na literałach ciągów w kodzie. Oznacza to, że jeśli masz w kodzie dwa równoważne ciągi literałów (nawet jeśli należą one do różnych klas), oba będą odnosić się do tego samego String
obiektu. To sprawia, że ==
operator wraca true
częściej niż można by się spodziewać.