Niezmienność ciągów w Javie

218

Rozważ następujący przykład.

String str = new String();

str  = "Hello";
System.out.println(str);  //Prints Hello

str = "Help!";
System.out.println(str);  //Prints Help!

Teraz w Javie obiekty String są niezmienne. Dlaczego więc obiektowi strmożna przypisać wartość „Pomoc!”. Czy nie jest to sprzeczne z niezmiennością ciągów w Javie? Czy ktoś może mi wyjaśnić dokładną koncepcję niezmienności?

Edytować:

Dobrze. Teraz rozumiem, ale tylko jedno pytanie uzupełniające. Co z następującym kodem:

String str = "Mississippi"; 
System.out.println(str); // prints Mississippi 

str = str.replace("i", "!"); 
System.out.println(str); // prints M!ss!ss!pp! 

Czy to oznacza, że ​​dwa obiekty są tworzone ponownie („Mississippi” i „M! Ss! Ss! Pp!”), A odniesienie strwskazuje na inny obiekt po replace()metodzie?

Lekki uchwyt
źródło
str jest TYLKO odniesieniem, a nie samym obiektem
ahmednabil88,
Mam nadzieję, że to pomoże pushkarrajpujari.com/article/strings-in-java
Pushkarraj Pujari

Odpowiedzi:

316

strnie jest przedmiotem, to odniesienie do obiektu. "Hello"i "Help!"są dwoma odrębnymi Stringprzedmiotami. 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. s2nadal wskazuje na ten sam obiekt, na który początkowo s1wskazywaliśmy. Ustawianie s1się "Help!"tylko zmienia odniesienia , podczas gdy Stringobiekt 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 oldCharw bieżącym ciągu znajduje się jedno lub więcej wystąpień , wykonaj kopię bieżącego ciągu, w którym wszystkie wystąpienia oldCharzostaną zastąpione newChar.
  • Jeśli oldCharnie ma go w bieżącym ciągu, zwróć bieżący ciąg.

Tak, "Mississippi".replace('i', '!')tworzy nowy Stringobiekt. 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.

gustafc
źródło
15
+1 dla metody fikcyjnej pokazuje różnicę między niezmiennym przedmiotem a innymi.
Zappi
1
Dzięki gustafc za prawidłowe przykłady i jasne wyjaśnienie .... Ale czy możesz po prostu odpowiedzieć na edytowaną część pytania? To wyjaśni moje zrozumienie.
Light_handle
17
Nigdy wcześniej nie widziałem takiej odpowiedzi. Omówiłem każdy szczegół.
Michael 'Maik' Ardan
+1 Oto pomysł, niezmienne obiekty w java są jak kopiowane według wartości, możesz mieć 2 odwołania do ciągu, ale powinieneś rozważyć je 2 oddzielne ciągi, ponieważ jest niezmienny, a praca z jednym z nich nie wpłynie na inne
Khaled.K
1
Java - im więcej myślisz, że wiesz, tym mniej naprawdę wiesz.
zeeshan
23

Obiekt, który się strodwołuje, może się zmienić, ale Stringsame obiekty nie mogą.

StringObiektów zawierających ciąg znaków "Hello"i "Help!"nie może zmieniać ich wartości, stąd są one niezmienne.

Niezmienność Stringobiektów nie oznacza, że ​​odniesienia do obiektu nie mogą ulec zmianie.

Jednym ze sposobów, w jaki można zapobiec strzmianie odwołania, jest zadeklarowanie go jako final:

final String STR = "Hello";

Teraz próba przypisania innej Stringdo STRspowoduje błąd kompilacji.

coobird
źródło
Ale w tym przypadku obiektem String jest „str”, który najpierw zawiera wartość „Hello”, a następnie otrzymuje nową wartość „Help!”. Co dokładnie masz na myśli przez „Obiekty String zawierające ciąg„ Hello ”i„ Help! ”Nie mogą zmienić swoich wartości, dlatego są niezmienne. ??? Wybacz mi, jeśli to głupie pytanie. Ale iv
muszę
2
czy masz szansę, że każdy próbował zaprogramować w C? Wystarczy przeczytać podkład na wskaźnikach, a doskonale zrozumiesz odpowiedź Coobirda.
Ryan Fernandes
Widzisz ... Właśnie tego chcę uniknąć ... Wiem, że jesteś świetnym programistą ... i właśnie próbuję nauczyć się tutaj java ... Więc jeśli możesz poprawnie odpowiedzieć na moje pytanie, odpowiedz na nie ... ,
Light_handle
Mylicie odniesienia i obiekty - strnie „obiekt” to odniesienie do obiektu. Jeśli String str = "Hello";po String anotherReference = str;tym nie masz 2 obiektów String, masz jeden obiekt (dosłownie „Hello”) i 2 odniesienia do niego ( stri anotherReference).
Nate,
Nie mam uprawnień do edycji, ale gdybym to zrobił, edytowałbym pierwsze zdanie coobirds na: „Odwołania str mogą ulec zmianie, ale same obiekty String nie mogą.”
j3App
10

Light_handle Polecam lekturę Rozmiar miseczki - opowieść o zmiennych i wartościach proszę o podanie (Rozmiar miseczki kontynuowany) . To bardzo pomoże w czytaniu powyższych postów.

Przeczytałeś je? Tak. Dobry.

String str = new String();

Tworzy to nowy „pilot” o nazwie „ str” i ustawia wartość new String()(lub "").

np. w pamięci tworzy to:

str --- > ""

str  = "Hello";

To następnie zmienia pilot „ str”, ale nie modyfikuje oryginalnego ciągu "".

np. w pamięci tworzy to:

str -+   ""
     +-> "Hello"

str = "Help!";

To następnie zmienia pilot „ str”, ale nie modyfikuje oryginalnego ciągu ""lub obiektu, na który obecnie wskazuje pilot.

np. w pamięci tworzy to:

str -+   ""
     |   "Hello"
     +-> "Help!"
Michael Lloyd Lee mlk
źródło
Czy „” i „Hello” są zbierane śmieci?
Prabin Timsina
@PrabinTimsina To powinno być naprawdę nowe pytanie. Odpowiedź: stackoverflow.com/questions/15324143/…
Michael Lloyd Lee mlk
9

Rozbijmy to na części

String s1 = "hello";

Ta instrukcja tworzy ciąg zawierający hello i zajmuje miejsce w pamięci, tj. W stałej puli ciągów i przypisuje go do obiektu odniesienia s1

String s2 = s1;

Ta instrukcja przypisuje ten sam ciąg hello do nowego odwołania s2

         __________
        |          |
s1 ---->|  hello   |<----- s2
        |__________| 

Oba odniesienia wskazują na ten sam ciąg, więc wypisz tę samą wartość, jak poniżej.

out.println(s1);    // o/p: hello
out.println(s2);    // o/p: hello

Chociaż String jest niezmienny , przypisanie może być możliwe, więc s1 będzie teraz odnosił się do nowego stosu wartości .

s1 = "stack";    
         __________
        |          |
s1 ---->|  stack   |
        |__________|

Ale co z obiektem s2, który wskazuje na cześć , będzie taki, jaki jest.

         __________
        |          |
s2 ---->|  hello   |
        |__________|

out.println(s1);    // o/p: stack
out.println(s2);    // o/p: hello

Ponieważ String jest niezmienny Java Virtual Machine nie pozwoli nam modyfikować łańcucha s1 za pomocą jego metody. Stworzy wszystkie nowe obiekty String w puli w następujący sposób.

s1.concat(" overflow");

                 ___________________
                |                   |
s1.concat ----> |  stack overflow   |
                |___________________|

out.println(s1);    // o/p: stack
out.println(s2);    // o/p: hello
out.println(s1.concat); // o/p: stack overflow

Zauważ, że jeśli String byłby zmienny, to wynik byłby

out.println(s1);    // o/p: stack overflow

Teraz możesz być zaskoczony, dlaczego String ma takie metody, jak concat () do modyfikacji. Poniższy fragment usunie zamieszanie.

s1 = s1.concat(" overflow");

Tutaj przypisujemy zmodyfikowaną wartość ciągu z powrotem do odwołania s1 .

         ___________________
        |                   |
s1 ---->|  stack overflow   |
        |___________________|


out.println(s1);    // o/p: stack overflow
out.println(s2);    // o/p: hello

Właśnie dlatego Java zdecydowała, że String będzie klasą końcową. W przeciwnym razie każdy może modyfikować i zmieniać wartość łańcucha. Mam nadzieję, że to trochę pomoże.

Shailesh Sonare
źródło
6

Obiekt łańcucha, do którego najpierw odwołano, strnie został zmieniony, jedyne, co zrobiłeś, to strodwołanie się do nowego obiektu łańcucha.

daveb
źródło
5

Ciąg nie zmieni się, odniesienie do niego ulegnie zmianie. Mylisz niezmienność z pojęciem finalpól. Jeśli pole zostanie zadeklarowane jako final, po przypisaniu nie można go ponownie przypisać.

akf
źródło
5

Jeśli chodzi o zastąpienie części pytania, spróbuj:

String str = "Mississippi"; 
System.out.println(str); //Prints Mississippi 

String other = str.replace("i", "!"); 
System.out.println(str); //still prints Mississippi 
System.out.println(other);  // prints M!ss!ss!pp!
użytkownik85421
źródło
4

Chociaż Java próbuje to zignorować, strjest niczym więcej niż wskaźnikiem. Oznacza to, że kiedy piszesz po raz pierwszy str = "Hello";, tworzysz obiekt, który strwskazuje. Podczas zmiany przypisania strprzez pisanie str = "Help!";tworzony jest nowy obiekt, a stary "Hello"obiekt jest zbierany na śmiecie, gdy tylko Java ma na to ochotę .

twolfe18
źródło
3

Niezmienność oznacza, że ​​wartość tworzonego obiektu nie może się zmienić, nigdy nie można zmienić „Cześć” w „Pomoc!”.

Zmienna str jest odniesieniem do obiektu, gdy przypisujesz nową wartość do str, nie zmieniasz wartości obiektu, do którego się odwołuje, odwołujesz się do innego obiektu.

Preston Guillot
źródło
3

Klasa string jest niezmienna i nie można zmienić wartości niezmiennego obiektu. Ale w przypadku Ciągu, jeśli zmienisz wartość ciągu, spowoduje to utworzenie nowego ciągu w puli ciągów, a następnie odniesienie ciągu do tej wartości, a nie do starszej. w ten sposób ciąg jest niezmienny. Weźmy swój przykład,

String str = "Mississippi";  
System.out.println(str); // prints Mississippi 

utworzy jeden ciąg „Mississippi” i doda go do puli ciągów, więc teraz str wskazuje na Mississippi.

str = str.replace("i", "!");  
System.out.println(str); // prints M!ss!ss!pp! 

Ale po powyższej operacji utworzony zostanie kolejny ciąg „M! Ss! Ss! Pp!” i zostanie dodany do puli ciągów. a teraz str wskazuje na M! ss! ss! pp !, a nie Mississippi.

w ten sposób, kiedy zmienisz wartość obiektu string, utworzy on jeszcze jeden obiekt i doda go do puli stringów.

Miejmy jeszcze jeden przykład

String s1 = "Hello"; 
String s2 = "World"; 
String s = s1 + s2;

ta powyżej trzy linie doda trzy obiekty łańcucha do puli łańcuchów.
1) Witaj
2) Świat
3) HelloWorld

Nirav Chhatrola
źródło
2

Posługiwać się:

String s = new String("New String");
s.concat(" Added String");
System.out.println("String reference -----> "+s); // Output: String reference -----> New String

Jeśli widzisz tutaj, używam concatmetody, aby zmienić oryginalny ciąg, czyli „Nowy ciąg” z ciągiem „Dodany ciąg”, ale nadal otrzymałem wynik jak poprzednio, stąd dowodzi, że nie można zmienić odwołania do obiektu klasy String, ale jeśli zrobisz to przez klasę StringBuilder, zadziała. Jest wymieniony poniżej.

StringBuilder sb = new StringBuilder("New String");
sb.append(" Added String");
System.out.println("StringBuilder reference -----> "+sb);// Output: StringBuilder reference -----> New String Added String
Nihar Nayak
źródło
2

Jak powiedział Linus Tolvards:

Rozmowa jest tania. Pokaż mi kod

Spójrz na to:

public class Test{
    public static void main(String[] args){

        String a = "Mississippi";
        String b = "Mississippi";//String immutable property (same chars sequence), then same object

        String c = a.replace('i','I').replace('I','i');//This method creates a new String, then new object
        String d = b.replace('i','I').replace('I','i');//At this moment we have 3 String objects, a/b, c and d

        String e = a.replace('i','i');//If the arguments are the same, the object is not affected, then returns same object

        System.out.println( "a==b? " + (a==b) ); // Prints true, they are pointing to the same String object

        System.out.println( "a: " + a );
        System.out.println( "b: " + b );

        System.out.println( "c==d? " + (c==d) ); // Prints false, a new object was created on each one

        System.out.println( "c: " + c ); // Even the sequence of chars are the same, the object is different
        System.out.println( "d: " + d );

        System.out.println( "a==e? " + (a==e) ); // Same object, immutable property
    }
}

Dane wyjściowe to

a==b? true
a: Mississippi
b: Mississippi
c==d? false
c: Mississippi
d: Mississippi
a==e? true

Pamiętaj więc o dwóch rzeczach:

  • Ciągi są niezmienne, dopóki nie zastosujesz metody, która manipuluje i utworzy nową (przypadki C i D).
  • Metoda Replace zwraca ten sam obiekt String, jeśli oba parametry są takie same
etlapa
źródło
0

Dla tych, którzy zastanawiają się, jak przełamać niezmienność String w Javie ...

Kod

import java.lang.reflect.Field;

public class StringImmutability {
    public static void main(String[] args) {
        String str1 = "I am immutable";
        String str2 = str1;

        try {
            Class str1Class = str1.getClass();
            Field str1Field = str1Class.getDeclaredField("value");

            str1Field.setAccessible(true);
            char[] valueChars = (char[]) str1Field.get(str1);

            valueChars[5] = ' ';
            valueChars[6] = ' ';

            System.out.println(str1 == str2);
            System.out.println(str1);
            System.out.println(str2);           
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }
}

Wynik

true
I am   mutable
I am   mutable
martynas
źródło
0

Sznurek jest niezmienny . Co oznacza, że ​​możemy zmienić tylko odniesienie .


String a = "a";
System.out.println("String a is referencing to "+a); // Output: a

a.concat("b");
System.out.println("String a is referencing to "+a); // Output: a

a = a.concat("b");
System.out.println("String a has created a new reference and is now referencing to "+a); // Output: ab
DeathRs
źródło
0

W Javie obiekty są ogólnie dostępne przez odwołania. W twoim fragmencie kodu znajduje się odwołanie, które jest najpierw przypisane do „Witaj” (automatycznie utworzony obiekt lub pobrany ze stałej puli ), a następnie przypisałeś inny obiekt „Pomoc!” do tego samego odniesienia. Należy zauważyć, że odniesienie jest takie samo i zmodyfikowane, ale obiekty są różne. Jeszcze jedną rzecz w twoim kodzie uzyskałeś dostęp do trzech obiektów,

  1. Po wywołaniu new String ().
  2. Po przypisaniu „cześć”.
  3. Po przypisaniu „pomocy!”.

Wywołanie new String () tworzy nowy obiekt, nawet jeśli istnieje on w puli łańcuchów, więc na ogół nie należy go używać. Aby umieścić ciąg utworzony z nowej funkcji String () w puli ciągów, możesz wypróbować tę intern()metodę.

Mam nadzieję, że to pomoże.

Nayan Srivastava
źródło
0

Niezmienność mogę powiedzieć, że nie można zmienić samego łańcucha. Załóżmy, że masz ciąg x, którego wartość to „abc”. Teraz nie możesz zmienić łańcucha, to znaczy nie możesz zmienić żadnego znaku / znaków w „abc”.

Jeśli musisz zmienić dowolny znak / ciągi, możesz użyć tablicy znaków i zmutować ją lub użyć StringBuilder.

String x = "abc";
x = "pot";
x = x + "hj";
x = x.substring(3);
System.out.println(x);

char x1[] = x.toCharArray();
x1[0] = 's';
String y = new String(x1);
System.out.println(y);

Wynik:

hj
sj
Sumedha Khatter
źródło
0

Lub możesz spróbować:

public class Tester
{
public static void main(String[] args)
{
 String str = "Mississippi"; 
 System.out.println(str); // prints Mississippi 
 System.out.println(str.hashCode());

 str = str.replace("i", "!"); 
 System.out.println(str); // prints M!ss!ss!pp! 
 System.out.println(str.hashCode());
 }
 }

To pokaże, jak zmienia się kod skrótu.

użytkownik1554868
źródło
0

Ciąg jest niezmienny, oznacza to, że nie można zmienić samego obiektu, ale można zmienić odwołanie do obiektu. Kiedy wywołałeś a = „ty”, tak naprawdę zmieniasz odniesienie a na nowy obiekt utworzony przez dosłowny ciąg „ty”. Zmiana obiektu oznacza użycie jego metod do zmiany jednego z jego pól (lub pola są publiczne i nie są ostateczne, dzięki czemu można je aktualizować z zewnątrz bez dostępu do nich metodami), na przykład:

Foo x = new Foo("the field");
x.setField("a new field");
System.out.println(x.getField()); // prints "a new field"

Będąc w niezmiennej klasie (zadeklarowanej jako końcowa, aby zapobiec modyfikacji przez dziedziczenie) (jej metody nie mogą modyfikować swoich pól, a także pola są zawsze prywatne i zaleca się, aby były ostateczne), na przykład Ciąg, nie można zmienić bieżącego Ciąg, ale użytkownik może zwrócić nowy ciąg znaków, tzn .:

String s = "some text";
s.substring(0,4);
System.out.println(s); // still printing "some text"
String a = s.substring(0,4);
System.out.println(a); // prints "some"
e2rabi
źródło
0

W tym przypadku niezmienność oznacza, że ​​instancja może wskazywać na inne odwołanie, ale oryginalna treść ciągu nie zostanie zmodyfikowana w pierwotnym odwołaniu. Pozwól, że wyjaśnię pierwszy podany przez ciebie przykład. Pierwszy ciąg wskazuje na „Hello”, jest OK do tego. Drugi raz wskazuje na „Pomoc!”. Tutaj zaczął wskazywać „Pomoc!” odwołanie do ciągu „Hello” zostało utracone i nie możemy go odzyskać.

W rzeczywistości, gdy str spróbuje zmodyfikować istniejącą zawartość, wówczas zostanie wygenerowany kolejny nowy ciąg i str zacznie wskazywać na to odwołanie. Widzimy więc, że ciąg w oryginalnym odwołaniu nie jest modyfikowany, ale jest bezpieczny w swoim odwołaniu, a instancja obiektu zaczęła wskazywać na inne odwołanie, więc niezmienność jest zachowana.

Afzal Ahmad
źródło
0

Bardzo późno na odpowiedź, ale chciałem przekazać zwięzłą wiadomość od autora klasy String w Javie

Ciągi są stałe; ich wartości nie można zmienić po ich utworzeniu. Bufory łańcuchów obsługują łańcuchy zmienne. Ponieważ obiekty String są niezmienne, można je udostępniać.

Z tej dokumentacji można wywnioskować, że wszystko, co zmienia ciąg, zwraca inny obiekt (który może być nowy lub internowany i stary). Nie tak subtelna wskazówka na ten temat powinna pochodzić z podpisu funkcji. Pomyśl o tym: „Dlaczego sprawili, że funkcja na obiekcie zwróciła obiekt zamiast statusu?”.

public String replace(char oldChar, char newChar) 

Również jeszcze jedno źródło, które wyraźnie wyjaśnia to zachowanie (z dokumentacji funkcji zastępowania)

Zwraca nowy ciąg wynikający z zamiany wszystkich wystąpień oldChar w tym ciągu na newChar.

Źródło: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replace(char,%20char)

  • autor Lee Boynton
  • autor Arthur van Hoff
  • autor Martin Buchholz
  • autor Ulf Zibis

Źródło: JavaDoc of String.

Ajeet Ganga
źródło
0

Łańcuch obiektowy - same metody są „niezmienne”. Ta akcja nie powoduje żadnych zmian: „letters.replace („ bbb ”,„ aaa ”);”

Ale przypisanie danych powoduje zmiany w treści Strings:

    letters = "aaa";
    letters=null;
    System.out.println(letters);
    System.out.println(oB.hashCode());
    System.out.println(letters);
    letters = "bbbaaa";
    System.out.println(oB.hashCode());
    System.out.println(letters);

// Kod skrótu ciągu Obiekt nie zmienia się.

Loshen Naicker
źródło
0

Jeśli HELLOjest to Twój Ciąg, nie możesz zmienić HELLOna HILLO. Ta właściwość nosi nazwę właściwości niezmienności.

Możesz mieć wiele zmiennych typu String wskaźnika, aby wskazywać łańcuch HELLO.

Ale jeśli HELLO jest char Array, możesz zmienić HELLO na HILLO. Na przykład,

char[] charArr = 'HELLO';
char[1] = 'I'; //you can do this

Języki programowania mają niezmienne zmienne danych, dzięki czemu można ich używać jako kluczy w parze klucz-wartość.

Uddhav Gautam
źródło
0

Wyjaśniłbym to prostym przykładem


rozważ dowolną tablicę znaków: np. char a [] = {'h', 'e', ​​'l', 'l', 'o'}; i ciąg: String s = "hello";


na tablicy znaków możemy wykonywać operacje takie jak drukowanie tylko trzech ostatnich liter przy użyciu iteracji tablicy; ale w ciągu musimy utworzyć nowy obiekt String i skopiować wymagany podciąg, a jego adres będzie w nowym obiekcie string.

na przykład

***String s="hello";
String s2=s.substrig(0,3);***

więc s2 będzie miał „hel”;

Aadesh Nirfarake
źródło
-1

Łańcuch w Javie w Immutable i Final oznacza po prostu, że nie można go zmienić ani zmodyfikować:

Przypadek 1:

class TestClass{  
 public static void main(String args[]){  
   String str = "ABC";  
   str.concat("DEF");  
   System.out.println(str);  
 }  
} 

Wyjście: ABC

Powód: str odwołania do obiektu nie jest zmieniany, w rzeczywistości tworzony jest nowy obiekt „DEF”, który znajduje się w puli i nie ma żadnego odniesienia (tj. Został utracony).

Przypadek 2:

class TestClass{  
 public static void main(String args[]){  
   String str="ABC";  
   str=str.concat("DEF");  
   System.out.println(str);  
 }  
}  

Wyjście: ABCDEF

Powód: W tym przypadku str odnosi się teraz do nowego obiektu „ABCDEF”, dlatego drukuje ABCDEF, tzn. Poprzedni obiekt str „ABC” jest tracony w puli bez odniesienia.

Affy
źródło
-1

Ponieważ String jest niezmienny, więc zmiany nie wystąpią, jeśli nie przypiszesz zwróconej wartości funkcji do string. Więc w swoim pytaniu przypisz wartość funkcji swap zwróconej do s.

s = zamiana (s, n1, n2); wówczas zmieni się wartość ciągu s.

Otrzymywałem również niezmienioną wartość, gdy pisałem program, aby uzyskać ciąg permutacji (chociaż nie daje wszystkich permutacji, ale jest to na przykład odpowiedź na twoje pytanie)

Oto przykład.

> import java.io.*;  public class MyString { public static void
> main(String []args)throws IOException {  BufferedReader br=new
> BufferedReader(new InputStreamReader(System.in));  String
> s=br.readLine().trim(); int n=0;int k=0;  while(n!=s.length()) {
> while(k<n){  swap(s,k,n); System.out.println(s); swap(s,k,n); k++; }
> n++; } }  public static void swap(String s,int n1,int n2) { char temp;
> temp=s.charAt(n1); StringBuilder sb=new StringBuilder(s);
> sb.setCharAt(n1,s.charAt(n2)); sb.setCharAt(n2,temp); s=sb.toString();
> } }

ale nie otrzymywałem permutowanych wartości ciągu z powyższego kodu. Więc przypisałem zwróconą wartość funkcji zamiany do ciągu i otrzymałem zmienione wartości ciągu. po przypisaniu zwróconej wartości otrzymałem permutowane wartości ciągu.

/import java.util.*; import java.io.*; public class MyString { public static void main(String []args)throws IOException{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 
String s=br.readLine().trim(); int n=0;int k=0; 
while(n!=s.length()){ while(k<n){ s=swap(s,k,n); 
System.out.println(s); s=swap(s,k,n); k++; } n++; } } 
public static String swap(String s,int n1,int n2){
char temp; temp=s.charAt(n1); StringBuilder sb=new StringBuilder(s); sb.setCharAt(n1,s.charAt(n2)); sb.setCharAt(n2,temp); s=sb.toString(); return s; } }
Shivam Shukla
źródło
-1
    public final class String_Test {

    String name;
    List<String> list=new ArrayList<String>();

    public static void main(String[] args) {

        String_Test obj=new String_Test();
        obj.list.add("item");//List will point to a memory unit- i.e will have one Hashcode value #1234

        List<String> list2=obj.list; //lis1 also will point to same #1234

        obj.list.add("new item");//Hashcode of list is not altered- List is mutable, so reference remains same, only value in that memory location changes

        String name2=obj.name="Myname"; // name2 and name will point to same instance of string -Hashcode #5678
        obj.name = "second name";// String is Immutable- New String HAI is created and name will point to this new instance- bcoz of this Hashcode changes here #0089

        System.out.println(obj.list.hashCode());
        System.out.println(list2.hashCode());
        System.out.println(list3.hashCode());

        System.out.println("===========");
        System.out.println(obj.name.hashCode());
        System.out.println(name2.hashCode());
    }
}

Będzie produkować umieścić coś takiego

1419358369 1419358369

103056 65078777

Celem niezmiennego obiektu jest to, że jego wartość nie powinna być zmieniana po przypisaniu. Zwróci nowy obiekt za każdym razem, gdy spróbujesz go zmienić w oparciu o implementację. Uwaga: Aby uniknąć tego, można użyć bufora łańcuchowego zamiast łańcucha.

Na twoje ostatnie pytanie: będziesz miał jedno odwołanie i 2 ciągi w puli ciągów. Z wyjątkiem tego, że odniesienie wskaże na m! Ss! Ss! Pp!

Arasn
źródło