This was a question on an exam. Luckily I picked the right answer, but I still can't see why it's right.
Consider this program:
class D {
protected C c;
public D(C c) {
this.c = new C(c);
}
public C getC() {
return c;
}
public void setC(C c) {
this.c = c;
}
}
class C {
protected String s;
public C(String s) {
this.s = s;
}
public C(C c) {
this(c.s);
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public static void main(String[] args) {
C c1 = new C("1");
C c2 = new C("2");
D[] d = {
new D(c1), new D(c1), new D(c2), new D(c2)
};
d[0] = d[3];
c1.setS("3");
String r = "";
for (D i: d) {
r += i.getC().getS();
}
System.out.println(r);
}
}
It'll print 2122. I would expect 2322 however (I'm clearly wrong when you run the code). My reasoning behind that:
In the third line of the main method, four instances of D get initialized.
The constructor of D makes a new instance of C. An instance of C has a String variable which points somewhere to a spot in the memory. Now the instance variable c, let's call it c3, of the object in d[1] has a instance variable (type String), let's call it s3, pointing to the same memory as the String s1, variable of c1.
So when we change s1, I'd expect the value of s3 also to change, since it's pointing to the same spot in the memory.
On a side note, if you change the constructor of D, see below, you'll get 2322 instead. Which I'd expect, since now the variable c3 in d[1] is pointing directly towards the memory location of c1.
public D(C c) {
this.c = c;
}
My thoughts so far on the explanation (could be wrong):
- When initializing the instance variable
s1/s3, newStringobjects get made (so far I assumed they were pointing towards"1"in theStringpool, since the constructor ofCmakes it look that way) - When changing
s1, it's pointer will be redirected towards"3"in theStringpool. Rather than"1"becoming"3"in the pool.
Could anyone explain this behaviour? What are the errors in my (faulty) reasoning?