Let's keep track of reference variables and objects as we go thru the code...
in main() the line: Integer i = new Integer(0); creates 1 ref var of type Integer, and 1 Integer object, and refers to ref var to the object.
Next we pass A COPY of i into the add3() method. I wish we didn't call it 'i' again - because now we have 2 reference variables both named 'i'.
(I think this is a tricky thing the test
makers try to do - they're testing two things at once, 1 do you understand passing stuff, 2 - do you know about 'hiding')
So now when we are in the add3() method, we still have 1 Integer object, but we have 2 ref vars, that both refer to that object! (The first is an instance variable, the second is a local variable.)
When the JVM runs the line: i = new Integer(val); We are creating a second Integer object, and referring it to the second ref var (unfortunately named i , jeez
So at this point the first i refers to the first Integer object (with a value of 0), and
The second i refers to the new Integer object (with a value of 3).
Finally, the S.O.P. prints the value of the first Integer object.
I think this would be easier to understand if you renamed ALL of the occurences of i in the add3 method to something else, maybe i2.
They really are different reference variables.