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, Strings 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.