The following Java code segment is from an AP Computer Science practice exam.
String s1 = \"ab\";
String s2 = s1;
s1 = s1 + \"c\";
System.out.println(s1 + \"
java.lang.String is an object, not a primitive.
What the code did in the first example is:
But to answer your question about reference or value, it's by reference.
It is not relevant whether String is treated like a primitive or like an object!
In the String example, the concatenation of two strings produces a new String instance, which is then assigned to s1. The variable s2 still references the unchanged(!) old String instance.
Assuming the BankAccount had a method to set the balance, which returns a new BankAccount, your example could look like this:
BankAccount b1 = new BankAccount(500); // 500 is initial balance parameter
BankAccount b2 = b1; // reference to the same object
b1 = b1.createNewAccountWithBalance(0); // create and reference a new object
System.out.println(b1.getBalance() + " " + b2.getBalance()); // prints "0 500"
The assertion
if Java treats String variables like references to any other Object, the answer would be "abc abc"
is incorrect. Java does treat String variables like references to any other Object. Strings are Objects but the answer is "abc ab" none the less.
The issue is not what the assignment operator does. The assignment operator assigns a reference to a String object in every case in your example.
The issue is what the concatenation operator ('+') does. It creates a new String object. As other have said, this is necessary because a String object is immutable but it is an issue of operator behaviour and not merely because String is immutable. The concatenation operator could return a new Object even if a String object were mutable.
In contrast, in your second example, b1.setBalance(0) does not create a new object, it modifies the existing object.
int s1 = 1;
int s2 = s1; // copies value, not reference
s1 = 42;
System.out.println(s1 + " " + s2); // prints "1 42"
Doesn't print "1 42"
but "42 1"
.Take each discrete line into consideration.First s1 assigns 1, then s2 assigns s1, which is 1 up until now(suppose java didn't see the third line yet.) Then java sees the third line and immediately changes s1 into 42.After that java was told to print what it knows so far, and that is s1 is 42 and s2 is 1(the old s1).
As for the String the same thing happens.
String s1 = "ab";
String s2 = s1;
s1 = s1 + "c";
System.out.println(s1 + " " + s2);// prints "abc ab".
Fort String it doesn't necessarily changes s1 but rather s1 now refers to a new String object in the heap memory, but the old "ab" object is still there, with a new reference of s2!
java Strings are immutable, so your reassignment actually causes your variable to point to a new instance of String rather than changing the value of the String.
String s1 = "ab";
String s2 = s1;
s1 = s1 + "c";
System.out.println(s1 + " " + s2);
on line 2, s1 == s2 AND s1.equals(s2). After your concatenation on line 3, s1 now references a different instance with the immutable value of "abc", so neither s1==s2 nor s1.equals(s2).
The difference between your BankAccount and a String is that a String is immutable. There is no such thing as 'setValue()' or 'setContent()'. The equivalent example with your bank account would be :
BankAccount b1 = new BankAccount(500); // 500 is initial balance parameter
BankAccount b2 = b1; // reference to the same object
b1 = new BankAccount(0);
System.out.println(b1.getBalance() + " " + s2.getBalance()); // prints "0 500"
So if you think of it this way (not actually what the compiler does, but functionally equivalent) the String concatenation scenario is:
String s1 = "ab";
String s2 = s1;
s1 = new String("abc");
System.out.println(s1 + " " + s2); //prints "abc ab"