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