Please see the following code:
public static void main(String[] args)
{
Test t1 = new Test();
t1.i = 1;
Test t0 = t1;
Test t2 = new Test();
t2.i = 2;
t0 = t2;
System.out.println(t1.i); //prints 1, I thought it would print 2
}
Is there any way to change t1 object after I got it from somewhere else by simple assignment without accessing t1 directly? (i.e. t1 = t0)
Here is an illustration of your program and what it does. Each state of the system is shown separated by a dashed line.
Note what happens when you do t0 = t1
. You assumed that this means that from now on, t0
and t1
are synonyms - whenever you use one, the other is affected. But in fact, t0
and t1
are simply two references to the same object.
Making a new assignment to t0
simply detached it from the "blue" object and re-attached it to the "violet" object.
As long as t0
and t1
were both pointing at the same object, any changes you make in the content of their pointed object (such as t0.i = 5
) would be seen by the other reference, because they both refer to the same object. But as soon as you assign something else to t0
, it loses its connection to t1
. After you do that, changing it will be reflected in t2
, which points to the same, "violet" object, not in t1
which still points to the old, "blue" one.
So:
- If you assign a new value to the reference - it no longer points to the same object as before, and any previous "double referencing" is lost.
- If you assign a new value to the content of the reference, it will be reflected in all reference variables that look at the same object.
Test t1 = new Test();
t1.i = 1
can be represented as
+-------+
| Test |
t1 -------> +-------+
| i (1) |
+-------+
now when you do
Test t0 = t1;
You are assigning to t0
same value as value from t1
, which means that now they hold same value (address to same Test instance), so your situation is
+-------+
t1 ----+ | Test |
+--> +-------+
t0 ----+ | i (1) |
+-------+
Now after this code
Test t2 = new Test();
t2.i = 2;
you will have
+-------+
t1 ----+ | Test |
+--> +-------+
t0 ----+ | i (1) |
+-------+
+-------+
| Test |
t2 -------> +-------+
| i (2) |
+-------+
and when you do
t0 = t2;
you change your situation to
+-------+
t1 ----+ | Test |
+--> +-------+
| i (1) |
t0 ----+ +-------+
|
| +-------+
| | Test |
t2 ----+--> +-------+
| i (2) |
+-------+
so as you see now t0
holds same object as object held by t2
reference, but t1
reference wasn't changed, and that is why
System.out.println(t1.i)
prints 1
.
What you did not understand here is that when doing t0 = t2
you replace the adress reference of t0
which is at that time the same as t1
by the reference of t2
so no, it won't affect t1
.
However, t0.i
would print 2.
But to answer your question
Is there any way to change t1 object after I got it from somewhere else
by simple assignment without accessing t1 directly? (i.e. t1 = t0)
Yes there is a way, check this snippet
Test t1 = new Test();
t1.i = 1;
Test t0 = t1;
t0.i = 3;
System.out.println(t1.i); //prints 3
This will modify t1.i
to 3
accessing t0.i
If you want to do it using the t2
object, then you can modify the value of i
directly :
Test t1 = new Test();
t1.i = 1;
Test t0 = t1;
Test t2 = new Test();
t2.i = 2;
t0.i = t2.i;
System.out.println(t1.i); //prints 2