In preparation for the SCJP (or OCPJP as it's now known) exam, I'm being caught out by some mock questions regarding pass-by-(reference)value and immutability.
My understanding, is that when you pass a variable into a method, you pass a copy of the bits that represent how to get to that variable, not the actual object itself.
The copy that you send in, points to the same object, so you can modify that object if its mutable, such as appending to a StringBuilder. However, if you do something to an immutable object, such as incrementing an Integer, the local reference variable now points to a new object, and the original reference variable remains oblivious to this.
Consider my example here :
public class PassByValueExperiment
{
public static void main(String[] args)
{
StringBuilder sb = new StringBuilder();
sb.append("hello");
doSomething(sb);
System.out.println(sb);
Integer i = 0;
System.out.println("i before method call : " + i);
doSomethingAgain(i);
System.out.println("i after method call: " + i);
}
private static void doSomethingAgain(Integer localI)
{
// Integer is immutable, so by incrementing it, localI refers to newly created object, not the existing one
localI++;
}
private static void doSomething(StringBuilder localSb)
{
// localSb is a different reference variable, but points to the same object on heap
localSb.append(" world");
}
}
Question : Is it only immutable objects that behave in such a manner, and mutable objects can be modified by pass-by-value references? Is my understanding correct or are there other perks in this behaviour?
To summarise the difference, mutable objects can change their state or contents and immutable objects can't change their state or content. Immutable Objects : These are of in-built types like int, float, bool, string, unicode, tuple. In simple words, an immutable object can't be changed after it is created.
String is an example of an immutable type. A String object always represents the same string. StringBuilder is an example of a mutable type. It has methods to delete parts of the string, insert or replace characters, etc.
Since the variables are just the reference to the objects, we get confused that we are passing the reference so java is passed by reference. However, we are passing a copy of the reference and hence it's pass by value.
final means that you can't change the object's reference to point to another reference or another object, but you can still mutate its state (using setter methods e.g). Whereas immutable means that the object's actual value can't be changed, but you can change its reference to another one.
There is no difference between mutable and immautable objects on the language level - immutability is purely a property of a class's API.
This fact is only muddled by autoboxing which allows ++
to be used on wrapper types, making it look like an operation on the object - but it's not really, as you've noticed yourself. Instead, it's syntactic sugar for converting the value to a primitive, incrementing that, converting the result back to the wrapper type and assigning a reference to that to the variable.
So the distinction is really between what the ++
operator does when it's used on a primitive vs. a wrapper, which doesn't have anything to do with parameter passing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With