str
nie jest przedmiotem, to odniesienie do obiektu. "Hello"
i "Help!"
są dwoma odrębnymi String
przedmiotami. W ten sposób str
wskazuje na ciąg. Możesz zmienić to, na co wskazuje , ale nie to, na co wskazuje .
Weź ten kod, na przykład:
String s1 = "Hello";
String s2 = s1;
// s1 and s2 now point at the same string - "Hello"
Teraz nie ma nic 1 moglibyśmy zrobić s1
, które wpływają na wartość s2
. Odnoszą się do tego samego obiektu - łańcucha "Hello"
- ale ten obiekt jest niezmienny i dlatego nie można go zmienić.
Jeśli zrobimy coś takiego:
s1 = "Help!";
System.out.println(s2); // still prints "Hello"
Widzimy tutaj różnicę między mutowaniem obiektu a zmianą referencji. s2
nadal wskazuje na ten sam obiekt, na który początkowo s1
wskazywaliśmy. Ustawianie s1
się "Help!"
tylko zmienia odniesienia , podczas gdy String
obiekt pierwotnie mowa pozostaje niezmieniona.
Gdyby łańcuchy były zmienne, moglibyśmy zrobić coś takiego:
String s1 = "Hello";
String s2 = s1;
s1.setCharAt(1, 'a'); // Fictional method that sets character at a given pos in string
System.out.println(s2); // Prints "Hallo"
Edytuj, aby odpowiedzieć na edycję OP:
Jeśli spojrzysz na kod źródłowy String.replace (char, char) (dostępny również w src.zip w katalogu instalacyjnym JDK - wskazówką jest, aby szukać tam, gdy zastanawiasz się, jak coś naprawdę działa), możesz zobaczyć, co robi to następująco:
- Jeśli
oldChar
w bieżącym ciągu znajduje się jedno lub więcej wystąpień , wykonaj kopię bieżącego ciągu, w którym wszystkie wystąpienia oldChar
zostaną zastąpione newChar
.
- Jeśli
oldChar
nie ma go w bieżącym ciągu, zwróć bieżący ciąg.
Tak, "Mississippi".replace('i', '!')
tworzy nowy String
obiekt. Ponownie, następujące są następujące:
String s1 = "Mississippi";
String s2 = s1;
s1 = s1.replace('i', '!');
System.out.println(s1); // Prints "M!ss!ss!pp!"
System.out.println(s2); // Prints "Mississippi"
System.out.println(s1 == s2); // Prints "false" as s1 and s2 are two different objects
Na razie twoją pracą domową jest sprawdzenie, co robi powyższy kod, jeśli zmienisz s1 = s1.replace('i', '!');
na s1 = s1.replace('Q', '!');
:)
1 Faktycznie, to jest możliwe, aby mutować strun (i innych niezmiennych obiektów). Wymaga refleksji i jest bardzo, bardzo niebezpieczny i nigdy nie należy go używać, chyba że faktycznie chcesz zniszczyć program.