3

このクローンの例は私を混乱させます。最初の 2 つの出力が、222 と 222 ではなく、111 と 222 になる方法がわかりません。これは「a2 = (A) a1.clone();」ではありませんか 行はa2がa1と同じになることを意味しますか?

コード:

public class Main {

    public static void main(String[] args) {
    A a1 = new A();
    A a2;
    B b1 = new B();
    B b2;

    a2 = (A) a1.clone();
    a2.setI(222);

    // Why the different output?
    System.out.println("a1 = " + a1 + " a1.i " + a1.getI()); // i = 111
    System.out.println("a2 = " + a2 + " a2.i " + a2.getI()); // i = 222

    b2 = (B) b1.clone();

    b2.setI(888); 
    b2.setJ(999); 

    System.out.println("b1 = " + b1 + " b1.i " + b1.getI() + " b1.j " +      b1.getJ());
    System.out.println("b2 = " + b2 + " b2.i " + b2.getI() + " b2.j " + b2.getJ()); 
}
}

public class A implements Cloneable {
    private int i = 111;
    @Override
    public Object clone() {
        try {
            A a = (A) super.clone();
            return a;
        } catch (CloneNotSupportedException e) {
            throw new InternalError();
        }
    }
    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
        }
    }

    public class B extends A {
    private int j = 222;

    @Override
    public Object clone() {  
        Object o = super.clone();               
        B b = (B) o;
        return b;
    }

    public int getJ() {
        return j;
    }

    public void setJ(int j) {
        this.j = j;
    }
}
4

5 に答える 5

5

値は操作でコピーされclone()ますが、同じ値を持つというだけで、2 つの異なるオブジェクトになります。

a2 = (A) a1.clone()

a1 とは完全に別の新しいオブジェクトを作成します。ただし、a1 の内部状態は a2 に複製されています。したがって、a2 を変更しても a1 には影響しません (クローン作成が適切に行われていれば!)

于 2013-03-05T16:31:19.197 に答える
2

いいえ、同じオブジェクトを指していません。したがって、の値の変更はオブジェクトa2に影響しませんa1clone()これが、オブジェクトの同じであるが別個のコピーを取得するという概念です。

あなたがこれをするとき

a1=(A)a2.clone();

コピー元のオブジェクトに関係なく、完全に新しいオブジェクトを取得します。

于 2013-03-05T16:33:34.260 に答える
2

クローンは、オブジェクトの「浅い」コピーのみを作成します。つまり、プリミティブ値とオブジェクト参照がコピーされます。あなたが望むのは(私は推測しています)、参照されたオブジェクト自体が複製される「深い」コピーです。これを行うための最も一般的な方法のいくつか:

  • Java ディープ クローニング ライブラリ
  • オブジェクトをシリアライズしてからデシリアライズします (警告: これは遅いです!)
  • 参照されるすべてのオブジェクトに実装し、参照するオブジェクトのメソッドでこれらのオブジェクトclone()を呼び出します。同様の方法でコピー コンストラクターを使用することもできます。clone()clone()
于 2013-03-05T16:38:09.743 に答える
0

ドキュメントから、Object.clone

このオブジェクトのコピーを作成して返します。「コピー」の正確な意味は、オブジェクトのクラスによって異なります。一般的な意図は、任意のオブジェクト x に対して、式:

x.clone() != x

真になります。

同じ文書からの続き:

このメソッドは、このオブジェクトのクラスの新しいインスタンスを作成し、そのすべてのフィールドを、割り当てによるかのように、このオブジェクトの対応するフィールドの内容で正確に初期化します。フィールドの内容自体は複製されません。したがって、このメソッドは、「ディープ コピー」操作ではなく、このオブジェクトの「浅いコピー」を実行します。

于 2013-03-05T16:41:39.780 に答える