Java String variable setting - reference or value?
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"
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"
Indeed, String is a class and it's assigned / passed by reference. But what's confusing is the statement:
String s = "abc";
Which suggests that String is a primitve ( like 'int x = 10;
' );
But that's only a shortcut, the statement 'String s = "abc";' is actually compiled as 'String s = new String( "abc" );
'
Just like 'Integer x = 10;
' is compiled as 'Integer x = new Integer( 10 );
'
This mechanism is called 'boxing'.
And more confusing is: there's a class 'Integer
' and a primitive 'int
',
but String doesn't have a primitive equivalent (allthough char[]
comes close)
Sije de Haan
In Java, String
objects are assigned and passed around by reference; it this respect they behave exactly like any other object.
However, String
s are immutable: there isn't an operation that modifies the value of an existing string in place, without creating a new object. For example, this means that s1 = s1 + "c"
creates a new object and replaces the reference stored in s1
with a reference to this new object.