这是考试中的一道题。幸运的是我选择了正确的答案,但我仍然不明白为什么它是正确的。
考虑这个程序:
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);
}
}
它会打印出来2122
。但是,我希望2322
(运行代码时我显然错了)。我的理由是:
在 main 方法的第三行,D
初始化了四个 get 实例。的构造函数D
创建 的新实例C
。的实例C
有一个String
变量,该变量指向内存中的某个点。现在对象的实例变量c
,我们称之为它c3
,d[1]
有一个实例变量(类型String
),我们称之为它,指向与 的变量s3
相同的内存。String s1
c1
所以当我们改变时s1
,我希望 的值s3
也会改变,因为它指向内存中的同一个点。
附带说明一下,如果您更改 的构造函数D
,请参见下文,您将得到2322
相反的结果。这是我所期望的,因为现在变量c3
ind[1]
直接指向c1
.
public D(C c) {
this.c = c;
}
到目前为止我对解释的想法(可能是错误的):
- 初始化实例变量
s1
/s3
时,会生成新String
对象(到目前为止,我假设它们指向池中"1"
,String
因为构造函数C
使它看起来那样) - 更改时
s1
,它的指针将被重定向到"3"
池中String
。而不是"1"
成为"3"
游泳池。
谁能解释这种行为?我的(错误的)推理中有什么错误?