Literały łańcuchowe są internowane automatycznie. Stąd s1 == s3 jest prawdziwe. Ciągi mogą być tworzone w puli stałych ciągów lub mogą być tworzone w przestrzeni sterty. Jeśli internujesz ciąg utworzony w stercie, ciąg będzie w stałej puli ciągów.
Podczas tworzenia literału łańcuchowego (String s1 = "ciąg znaków") łańcuch jest tworzony w puli stałej łańcuchowej. Ponadto pula stałych ciągów nie przechowuje duplikatów. Jeśli więc powiesz, że:
String s1 = "string one";
String s3 = "string one";
Zarówno s1, jak i s3 będą wskazywać na to samo wystąpienie ciągu w puli stałej ciągów. Zatem s1.equals (s3) będzie prawdziwe. I s1 == s3 również jest prawdziwe; ponieważ oba wskaźniki są takie same.
Jednak podczas wystąpienia ciąg przy użyciu „nowych” konstruktor
String s2 = new String("string one");
następnie s2 jest tworzone w przestrzeni sterty. Przestrzeń sterty jest innym obszarem pamięci niż stała puli ciągów znaków
Tak więc, podczas gdy s1.equals (s2) ma wartość true, s1 == s2 jest fałszywe; ponieważ będą wskazywać na różne obszary pamięci.
Można jednak skonwertować ciąg utworzony za pomocą "nowego" konstruktora, aby przejść do stałej puli ciągów, wywołując funkcję intern(). Tak więc s2.intern()
zwróci ciąg w puli stałej ciąg; chociaż s2 został pierwotnie utworzony w stercie.
Niezależnie od tego, czy jest to możliwe, czy nie, ale nie powinieneś tego robić.'==' jest dla _obiektowej tożsamości, _ nie porównuje łańcuchów. – paxdiablo
@paxdiablo: Jeśli zajmujesz się wyłącznie literałami ciągów, możesz użyć '=='. Ale dokumentowanie tego jest generalnie takim bólem, że łatwiej jest po prostu użyć 'equals()' na całej tablicy. –
tak, wiem o tym wszystkim. programowałem w Javie od lat i po prostu się zastanawiałem :). nie wygląda na to, że powinno tak być ... –