Kurs Java Podstawy - rozszerzony

JavaTraps 001 - odpowiedź

Pytanie dotyczyło poniżej przedstawionego kodu, a konkretnie, co pokaże się na ekranie po uruchomieniu kodu:

public class Test {
	public static void main(String args[]){
		String s1 = "Ala";
		String s2 = "Ala";
		System.out.println(s1==s2);
		System.out.println(s1.equals(s2));

		String s3 = s1;
		String s4 = new String("Ala");
		System.out.println(s3==s4);
		System.out.println(s3.equals(s4));
	}
}

Poprawna odpowiedź to: C) true true false true.

Zadać można pytanie dlaczego akurat tak? Przecież utworzyliśmy 4 obiekty typu String, które nie mają ze sobą związku. Metoda equals(), porównuje ogólnie w przypadku typów obiektowych (w zależności od tego jak została zdefiniowana) równość wewnętrznych pól obiektu. W przypadku Stringów sprawdzamy za jej pomocą, czy napis "Ala" równy jest innemu napisowi "Ala". No więc 2 z 4 wartości powinny być teraz oczywiste.

Ale zaraz, dlaczego porównanie s1==s2 zwraca true? Przecież to jest operator sprawdzający równość fizyczną, a nie strukturalną. Wszystko rozbija się w tym przypadku o działanie wirtualnej maszyny. Stringi, które są dokładnie takie same, są przez maszynę wirtualną lokowane w jednym miejscu pamięci (całkiem sprytne), dlatego porównanie dwóch takich samych napisów w Javie za pomocą operatora == zwróci nam true.

W takim razie, dlaczego przy porównaniu s3==s4 mamy już wartość false? Przy tworzeniu obiektu s4 użyliśmy słowa kluczowego new - tym samym wymusiliśmy utworzenie nowego, niezależnego obiektu. W tym przypadku mimo, iż jest to nadal ten sam napis "Ala" to jest już w całkiem innym miejscu pamięci.

Także dla pewności zawsze używaj do porównywanie zarówno obiektów jak i Stringów metody equals(). Dobrze zdefiniowana w pierwszej kolejności sprawdza właśnie równość fizyczną dwóch obiektów, także nie musisz się zbytnio martwić o to, że zużyje ona więcej zasobów.

Komentarze

Bałut

Czegoś nas jednak Sensei Spławski nauczył :P

wld

Powołujesz się na księgę Efektywne programowanie, a w kodzie używasz:
String s4 = new String("Ala"); // chapter 5 - item 5

wiem, że chodziło o przykład alokowania stringów w pamięci, ale warto było dodać, żeby w większości przypadków tak nie czynić.