1

So I was watching an introductory Java tutorial, and it said that if you declare a reference type, and another one equal to that object, if you change the first object, the second one will change as well. For example:

Point p1 = new Point(1, 1);
Point p2 = p1;
p1.x = 5;
System.out.println(p2);

and this would give me an output of

java.awt.Point[x=5,y=1]

However, I tried this with a String:

String s1 = "Hello, World!";
String s2 = s1;
s1 = "Goodbye, World!";
System.out.println(s2);

but I got

Hello, World!

as an output.

Why does this happen, and does it mean that Strings are a special type of reference types because they are used to commonly?

3 Answers3

2

Strings in Java are immutable objects. They never change. When you do a new assignment it simply creates a new String. The old one remains to be collected by the garbage collector. Your Point class is not an immutable object.

ojblass
  • 21,146
  • 22
  • 83
  • 132
  • So just to clarify, when you update point objects, you change the original object but if you update a string, it completely creates a new string so `s2` is still referring back to the original, unchanged one right? – dinosauce34 Dec 13 '20 at 00:00
  • 1
    @dinosauce34: You *do not* update a String. Re-assigning a new object to a variable does nothing to the old or the new object. This is the same for String as for any other object. – Thilo Dec 13 '20 at 02:14
  • The difference is that `p1.x = 5;` changes the object that `p1` points to. Whereas `s2 = s1` does not change the object previously pointed to by `s2` (or the object pointed to by `s1)`. – Thilo Dec 13 '20 at 02:16
2

I work with a lot of things in python and it is the same situation. Take a list, for example, which has multiple values stored. That will change when you've done the equivalent of your code in python. Strings will not change as you've said. The thing with code is that objects and classes like lists will change because they're not stored in memory. They are merely references, not new objects. When you reassign a string, assignment works properly because it is just one value.

James Huang
  • 848
  • 1
  • 7
  • 35
0

String is a 'special' object in java. It's an immutable object (Fixed and cannot be modified), and would be the only object that can be declared without the new keyword.

If you use StringBuilder, StringBuffer those are mutable String and your values will be modified upon change.

When you dive deeper, Java String comes with many confusing understanding. When you use "==", 2 different string with same value returns the same reference of the memory address. Eg.

String a1 = "abc"
String a2 = "abc"
a1 == a2 //returns true because a1 and a2 points to same reference (but not always!)
a1 == new String("abc") //returns false
/**Do use "equals", not == for string's value comparison**/

If you can wrap your mind around memory object references:

String s1 = "Hello, World!"; //let's say it's allocated to memory address 0x0012
String s2 = s1; //s2 points to same memory address 0x0012
s1 = "Goodbye, World!"; //s1 points to new memory address 0x1113
System.out.println(s2) //printing value in still in memory address 0x0012

It's equivalent as, s1 points to new Object, s2 points to the old Object.

and when you refer back to your Point example

Point p1 = new Point(1, 1);
Point p2 = p1; //p2 is referring to p1's memory address
p1.x = 5;  
p1 = new Point(2,2); //Assign to new memory address, here is like the line for s1="Goodbye,world"
System.out.println(p2.x); //You now still get 5, because it's still old object.

So to fix a string that is mutable, you need something like "Class"."method" to change in order to retain the same object being modified. Hence something like:

StringBuilder sb1 = new StringBuilder("Hello World");
StringBuilder sb2 = sb1;  //Points to same reference address.
sb1.append("Goodbye World");
System.out.println(sb2.toString()); //Now you get Hello WorldGoodbye World.
sb1.setLength(0).append("Goodbye World"); //clear then set to new value.
System.out.println(sb2.toString()); //Now you get Goodbye World.
Han
  • 728
  • 5
  • 17