After the System.arraycopy
, the two arrays are indeed shallow copies of each other. That is, you had a copy of the references to the StringBuilder
s. The objects referred to are the same.
num3: [ refA, refB ] num4: [ refA, refB ]
| | | |
| `-------> StringBuilder("Oak") <-------+-----'
`------------> StringBuilder("Pine") <------'
But then you change the reference in num3[0]
to point to a new StringBuilder
:
num3: [ refC, refB ] num4: [ refA, refB ]
| | | |
| `-------> StringBuilder("Oak") <-------+-----'
| StringBuilder("Pine") <------'
`------------> StringBuilder("Choc")
The underlying objects haven't changed. All you've done is changed what's referencing them.
System.arraycopy
is just like having a for
loop that copies the values in the arrays over, except it's much more efficient for large arrays (as modern CPUs have special instructions for bulk memory copying). You don't ever need it semantically; it's just a performance optimisation.