javanewbie javanewbie - 2 months ago 7x
Java Question

aliasing with StringBuffer

I am running this code:

public class testttt {
public static void main(String[] args){
ArrayList<StringBuffer> listOne = new ArrayList <StringBuffer>();
listOne.add(new StringBuffer("One"));
listOne.add(new StringBuffer("Two"));
listOne.add(new StringBuffer("Three"));

ArrayList <StringBuffer> listTwo = new ArrayList <StringBuffer>(listOne);
listOne.add(new StringBuffer("Four"));
for (StringBuffer str : listTwo) {

System.out.println("List One: " + listOne);
System.out.println("List Two: " + listTwo);


I thought by having the "new ArrayList" declaration when initializing listTwo I would have created a distinct array that would be independent from listOne. However, the output is:

List One: [One2, Two2, Three2, Four]
List Two: [One2, Two2, Three2]

I have a suspicion that the listTwo initialization only copied over the references from listOne, but I thought it would have been handled by the "new ArrayList" section.

Any explanation would be greatly appreciated!


By using the listOne for the listTwo construction, you are saying: "please copy those elements from the first list into the second list".

And then of course, java is doing "call-by-value". This means: "copying" doesn't mean the creation of new StringBuffers. It means that both lists hold references to the same StringBuffer objects.

Thus when you iterate the second list, and modify members of the second list, you see the effects on the first list as well.

So, the "real" answer is: always understand the concepts you are using; the "real" message here isn't the explanation; but the fact that one core part of being a programmer is to be very precise about the code you write, and to really understand each and every tiny bit of statement your put in your code. Everything has a certain meaning; and if you don't know them, your code will keep "surprising" you.