試験問題でした。幸いなことに、私は正しい答えを選びましたが、なぜそれが正しいのかはまだわかりません。
このプログラムを考えてみましょう:
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 メソッドの 3 行目で、Dget の 4 つのインスタンスが初期化されます。のコンストラクタはD、 の新しいインスタンスを作成しますC。のインスタンスにCはString、メモリ内のスポットを指す変数があります。ここで、 のオブジェクトのインスタンス変数c、それと呼びましょうはインスタンス変数 (タイプ ) を持ち、 の変数と同じメモリを指している と呼びましょう。c3d[1]Strings3String s1c1
したがって、 を変更すると、メモリ内の同じ場所を指しているため、s1の値も変更されることが予想されます。s3
補足として、 のコンストラクターを変更するとD、以下を参照してください2322。代わりに取得されます。c3の変数がd[1]のメモリ位置を直接指しているので、これは私が期待することですc1。
public D(C c) {
this.c = c;
}
これまでの説明に関する私の考え(間違っている可能性があります):
- インスタンス変数
s1/を初期化するs3と、新しいオブジェクトが作成されます (これまでのところ、コンストラクターがそのように見えるため、プール内Stringを指していると想定していました)"1"StringC - を変更する
s1と、そのポインターはプール内にリダイレクトさ"3"れStringます。"1"プールに入るよりも"3"。
誰でもこの動作を説明できますか? 私の(誤った)推論の誤りは何ですか?