Stringi - obiekty i referencje

Stringi - obiekty i referencje
EW
  • Rejestracja:ponad 11 lat
  • Ostatnio:prawie 4 lata
  • Postów:20
0

Próbuję pojąć stringi no i wiem, że można je stworzyć na dwa podstawowe sposoby

Kopiuj
String s1 = "test";
String s2 = "test";

Są to referencję do stringów o wartości test w puli stringów w stercie, więc robiąc s2 = "zmiana" nic w s1 się nie zmieni. Zmieni się tylko referencja s2.

Natomiast tworząc stringi w taki sposób:

Kopiuj
String s1 = new String("test");
String s2 = s1;

I teraz robiąc s2 = "zmiana" zmieni się tylko też s2, a myślałem, że tutaj zmieni się wartość tego stringa w s1 a tak się nie dzieje. Dlaczego?

Spróbowałem to na własnej klasie:

Kopiuj
public class Customer {
	private String name;
	private int age;
+konstruktor, settery i gettery
}

I później:

Kopiuj
 Customer mainCustomer = new Customer("Adam", 16);
 Customer anotherCustomer = mainCustomer;
 System.out.println("MainCustomer: " + mainCustomer.getName() + " " + mainCustomer.getAge());
 anotherCustomer.setName("Już nie Adam");
 System.out.println("MainCustomer: " + mainCustomer.getName() + " " + mainCustomer.getAge());
 System.out.println("anotherCustomer: " + anotherCustomer.getName() + " " + anotherCustomer.getAge());

Wynik będzie:

Kopiuj
MainCustomer: Adam 16
MainCustomer: Już nie Adam 16
anotherCustomer: Już nie Adam 16

Czym różni się tutaj obiekt Stringa i Customer, że działają inaczej. I czy jest sytuacja, że robiąc s2 = s1 i s2 = "zmiana", zmiana zajdzie też w s1?

edytowany 1x, ostatnio: ewazdomu
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
0

Zauważ, że robisz dwie różne rzeczy:

Kopiuj
// Twój przypadek ze stringami:
obiektA = obiektB; // to zmienia referencję trzymaną w obiektA (zmienia wartość zmiennej) - żadne dane obiektu jednak się nie zmieniają

// Twój przypadek z klientami:
obiektA.setCośtam(/* ...*/); // to zmienia dane trzymane wewnątrz obiektu

Zobacz pozostały 1 komentarz
Patryk27
Jeśli zrobisz obiektA = obiektB; obiektB.setCośtam("cośtam");, obiektA też będzie miał zmienione pole (ponieważ obydwa wskazują na ten sam obiekt pod spodem - mają tę samą referencję). Stringi w Javie są immutable, więc ciężej jest to udowodnić :-P
EW
Jeszcze jedno pytanie, czy jest jakaś możliwość aby modyfikując String s2 któremu przypisałem s1, zmienić coś w s1? Słyszałem o refleksji jednak nie znam tego zagadnienia jeszcze, więc nie wnikałem zbytnio.
Patryk27
Stringi są niemutowalne - raz utworzonego stringa nie możesz w żaden sposób zmienić.
EW
Więc gdy zrobię s2 = "zmiana" to s2 otrzyma nową referencję do stringa "zmiana" w pamięci. Niezmienność polega na tym, że konkretne miejsce w stercie zawsze trzyma tą samą wartość, a ten konkretny string będzie zawsze wskazywał na to samo miejsce w pamięci?
Patryk27
Niezmienność polega na tym, że raz utworzonego stringa nie możesz już zmienić (nie możesz zrobić np. str.replace("cośtam", "cośtam innego") czy str[5] = 'x';. Wszelkie str = strA + strB tworzą nową, zmienioną instancję stringa.
PM
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 3 lata
  • Lokalizacja:Poznań
0

s1 jest referencją do heapa natomiast s2 to string poola.

P0
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 6 lat
  • Postów:99
0

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.