2013-05-22 12 views
7

Próbuję zrozumieć ciąg stały basen, jak łańcuch znaków obiekty są zarządzane w stałej puli, nie jestem w stanie zrozumieć, dlaczego jestem coraz false z poniżej kod gdzie s2 == s4W jaki sposób tworzone są literały łańcuchowe?

public static void main(String[] args) { 
    String s1 = "abc"; 
    String s2 = "abcd"; 
    String s3 = "abc" +"d"; 
    String s4 = s1 + "d"; 
    System.out.println(s2 == s3); // OP: true 
    System.out.println(s2 == s4); // OP: false 
} 
+3

'" abc "+" d "' jest wyrażeniem stałym w czasie kompilacji, natomiast 's1 +" d "' nie jest. – johnchen902

Odpowiedz

12

Wyrażenie "abc" + "d" jest stałej ekspresji, a więc powiązanie prowadzi się kompilacji, co prowadzi do kodu, co odpowiada:

String s1 = "abc"; 
String s2 = "abcd"; 
String s3 = "abcd"; 
String s4 = s1 + "d"; 

wyrażenie s1 + "d" jest nie Stałe wyrażenie, a zatem jest wykonywane w realizacji czasu, tworząc nowy obiekt ciąg. Dlatego też, mimo że s2 i s3 odnoszą się do tego samego obiektu tekstowego (ze względu na ciągłe wstawianie ciągów znaków), s2 i s4 odnoszą się do różnych (ale jednakowych) obiektów tekstowych.

Aby uzyskać więcej szczegółowych informacji na temat wyrażeń stałych, zobacz stronę section 15.28 of the JLS.

+0

Jon - Naprawiłem to, co uważałem za niedopatrzenie w końcowych uwagach. Dobrze byłoby sprawdzić, czy to naprawdę miało na myśli. –

+0

@AndrzejDoyle: Tak, jest - dzięki. –

+4

Zauważ również, że jeśli zrobisz 's1' final, drugie porównanie wyświetli również' true', ponieważ w czasie kompilacji będzie wiadomo, że można go uznać za stały. –

0

s2 jest tworzony podczas kompilacji. Pamięć jest dla niego zarezerwowana i odpowiednio zapełniona.

s1 + "d" jest oceniany w czasie wykonywania. Ponieważ używasz dwóch różnych ciągów znaków (tzn. s1 jest zmienną, która teoretycznie może być dowolna), kompilator nie może z góry wiedzieć, że nie zamierza zmieniać wartości odwołania do obiektu.

Dlatego musi dynamicznie przydzielać pamięć.

Powiązane problemy