All variables, with the exception of primitive types, store references, not values.
First example
Integer i = 6;
Create a new Integer object (lets call it I1) and store a reference to it in i
ArrayList<Integer> ar = ArrayList<Integer>();
ar.add(i);`
Create an ArrayList, and store a reference to I1 in it
i = 8;
Create a new (different) Integer object (lets call it I2) and store a reference to it in i
So now, i = I2, and ar.get(0) = I1
Second example
MyC myc = new MyC();
Create a new MyC (let's call it C) and store a reference to in in myc
myc.i = 6;
Create a new Integer object (lets call it I1) and store a reference to it in C.i
ArrayList<MyC> ar = ArrayList<MyC>();
ar.add(myc);
Create an ArrayList, and store a reference to C in it.
myc.i = 8
Create a new Integer object (lets call it I2) and store a reference to it in C.i
So now myc = C, myc.i = I2, ar.get(0) = C, and therefore ar.get(0).i = I2.
Nothing is referencing I1 and it will be garbage collected.