First of all, in foo(myObject)
we are assigning something to final
, how is it possisble?
The object is not final
, the variable in main
is final
. So in main
, if you added myObject = somethingElse;
after your initial line that sets its value, it wouldn't compile because you can't put a new value in the variable. That has no effect on whether the object the variable refers to is mutable.
And the second thing, after foo()
was done, we'll get myObject
to be null, so how can we even print it?
There are two separate things called myObject
in your code:
A variable in main
A parameter in foo
Your code in foo
sets the parameter to null
, but that has no effect whatsoever on the variable in main
. (In fact, it's impossible for foo
to have any effect on the variable in main
; Java is a purely pass-by-value language. All foo
can do, as you've demonstrated, is modify the state of the object that both the variable and the parameter refer to, using the object reference passed into it as a parameter.)
Let's stop your code just before this line in foo
:
myObject.myInt = 1;
Here's what we have in memory (leaving out some details and irrelevancies):
+−−−−−−−−−−−−−−−−−−−−−−+
| variable "myObject" | foo can change the
+−−−−−−−−−−−−−−−−−−−−−−+ *state* of this
foo can't change this−−>| Ref22458 |−−−+ |
+−−−−−−−−−−−−−−−−−−−−−−+ | v
| +−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−−−−−−−−−+ +−−−>| object of type MyClass |
| parameter "myObject" | | +−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−−−−−−−−−+ | | myInt: 2 |
foo can change this−−−−>| Ref22458 |−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−−−−−−−−−+
...where "Ref22458" is just a name for the value of the object reference that points to the object you created in main
.
Once we execute the two lines in foo
:
myObject.myInt = 1;
myObject = null;
we have this in memory:
+−−−−−−−−−−−−−−−−−−−−−−+
| variable "myObject" | foo can change the
+−−−−−−−−−−−−−−−−−−−−−−+ *state* of this
foo can't change this−−>| Ref22458 |−−−+ |
+−−−−−−−−−−−−−−−−−−−−−−+ | v
| +−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−−−−−−−−−+ +−−−>| object of type MyClass |
| parameter "myObject" | | +−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−−−−−−−−−+ | | myInt: 1 |
foo can change this−−−−>| null |−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−−−−−−−−−+
Note how foo
could change the state of the object (myInt
is now 1
), and could change the value in the parameter myObject
(it's now null
), but couldn't change the value in the variable myObject
(for two reasons: it has no access to the variable [Java is pass-by-value], and the variable is final
).