Consider the following example:
public static void main(final String[] args) throws Exception {
final StringHolder holder = new StringHolder("old value");
System.out.println(holder);
reassignHolder(holder);
System.out.println(holder);
changeVal(holder);
System.out.println(holder);
}
static void reassignHolder(StringHolder holder) {
holder = new StringHolder("new value");
}
static void changeVal(StringHolder holder) {
holder.setVal("new value");
}
static class StringHolder {
private String val;
public StringHolder(String val) {
this.val = val;
}
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
@Override
public String toString() {
return "StringHolder{" + "val=" + val + '}';
}
}
In Java references are passed by value and (almost) everything is an object reference.
Here we have a mutable object that holds a String
- a StringHolder
.
When we call reassignHolder
what we actually do is copy our object reference and pass it to the method. When the method reassigns the reference nothing happens to our original reference as we are passing a copy.
When we call reassignHolder
we also pass a copy of our reference, but the method uses this reference to call a method on our object to change its val
variable. This will have an effect.
So the output is:
StringHolder{val=old value}
StringHolder{val=old value}
StringHolder{val=new value}
As String
is immutable, you can only carry out the first example rather than the second.