I would like to understand how primitive and object reference variable behaves differently. I have used the below code from OCA/OCP Java SE7 by Kathy Sierra as an example:
public class VariableTesting {
public static void main(String[] args) {
int a = 10;
System.out.println("a= " + a);
int b = a;
b = 30;
System.out.println("a= " + a + " after change it to b and b is " + b);
Dimension a1 = new Dimension(5, 10);
System.out.println("a1.height = " + a1.height);
Dimension b1 = a1;
b1.height = 30;
System.out.println("a1.height= " + a1.height + " after change to b1");
}
}
In the above piece of code, I'm getting the value of a = 10;
before and after changing the value of b
.
The output for the primitive variable case is:
a = 10
a = 10 after change it to b and b is 30
However, in object reference variable I'm getting a different value once I change the value of b1.height = 30;
The output for the reference variable case is:
a1.height = 10
a1.height = 30 after change to b1
It is mentioned in the book that in both case the bit pattern is copied and a new copy is placed. If this is true, then why we are getting different behavior?
This is the underpinning difference between a reference and a primitive. In both cases, you're getting the actual value, but only in the case of an object do you have a chance to impact the result of any other usages of it.
Let's walk through the code.
int a = 10;
int b = a;
These two declarations are saying the following:
a
.a
to an int identifier called b
.So far, so good. Nowhere do we say that a
is referenced by b
; we're only taking values.
If we declare:
b = 30;
We're saying take the value of 30 and assign it to the identifier b
.
We don't do anything with a
at that point; it already contains the value 10
. This is why a
and b
are different.
Now, when we get to the object, things don't really change on the surface...
Dimension a1 = new Dimension(5, 10);
Dimension b1 = a1;
We translate this as:
Dimension
identifier a1
.a1
to a Dimension
identifier b1
.We're still assigning values here, since Java is pass-by-value. The kicker here is that in Java, the value of an object is still a reference to that object.
By the above example, a1
and b1
are pointing to the same instance.
Now, when we state this:
b1.height = 30;
We're actually saying:
height
dereferenced through the value b1
.We're still referring to the value of b1
here, which is tied to a1
. This is why you see the difference; because a1
and b1
refer to the same value (which is the same reference), any change done through the identifier b1
is reflected through a1
.