13

clone()Javaでは浅いコピーですか?

最終的に、これはObject(最上位クラス)のclone()メソッドに到達します。このメソッドは、オブジェクトと同じクラスの新しいインスタンスを作成し、すべてのフィールドを新しいインスタンスにコピーします(「浅いコピー」)。

私はウィキペディアからこれを読みました。

なぜ浅いコピーなのかわかりません。clone()すべてのフィールドで新しいインスタンスを作成します。これは単なる深いコピーですか?混乱している。説明が必要です。

4

8 に答える 8

22

デフォルトObject.clone()は確かに浅いコピーです。CloneNotSupportedExceptionただし、オブジェクトが を実装しない限り、をスローするように設計されていますCloneable

を実装するときは、それ自体が複製可能なすべてのフィールドを呼び出して、ディープ コピーを行うようにオーバーライドCloneableする必要があります。clone()clone()

于 2011-03-11T23:00:15.643 に答える
8

他のオブジェクトへの参照のみをコピーするため、浅いコピーです。これらのクラスがあるとします:

class A {
    B variable
    A() {
        variable = new B();
    }
}

class B { }

次に、 A のインスタンスのクローンを作成します。

A firstA = new A();
A secondA = firstA.clone();

firstA と secondA の B インスタンスは同じになります。B インスタンスのコピーはありません。これが、 clone() が浅いコピーを行うと言われる理由です。

リンクしたページの図は、そのすべてを理解するのに役立ちます。

于 2011-03-11T23:08:31.733 に答える
5

余談ですが、Cloneable に関する Joshua Bloch の見解について誰も言及していないことに驚いています。

私の本でクローンについての項目を読んだことがあるなら、特に行間を読んだなら、クローンが深く壊れていると私が思うことがわかるでしょう。いくつかの設計上の欠陥があります。その最大のものは、Cloneable インターフェイスに clone メソッドがないことです。つまり、単純にうまくいかないということです。何かを Cloneable にしても、それで何ができるかはわかりません。代わりに、内部で何ができるかについて何かを述べています。super.clone を繰り返し呼び出すことで Object の clone メソッドを呼び出すことになった場合、このメソッドは元のフィールドのコピーを返すことを示しています。

于 2011-03-11T23:53:22.977 に答える
4

clone() は、すべてのフィールドのコピーを作成します。Java にはプリミティブ型と参照があります。オブジェクトを複製すると、すべてのプリミティブ フィールドのコピー (ディープ コピーのようなもの) を持つ新しいオブジェクトが取得されますが、すべての参照フィールドのコピーもあります。その結果、プリミティブのコピーと同じオブジェクトへの参照のコピーを所有する 2 つのオブジェクトが得られます。元のオブジェクトとコピーされたオブジェクトの両方が同じオブジェクトを使用します。

于 2011-03-11T23:03:56.360 に答える
3

一部のオブジェクトはディープ コピーを提供しません。たとえば、ArrayList はリストを複製しますが、リスト内の要素は複製しません。以下は、ArrayListのJavaDocからのものです。

public Object clone()

    Returns a shallow copy of this ArrayList instance. (The elements themselves are not copied.)
于 2011-03-11T23:02:51.517 に答える
2

Object.clone() のデフォルトの実装は浅いコピーです。この動作は、多数のプリミティブ フィールドまたは不変フィールドを持つ型の場合にも役立ちます。クローンメソッドを適切にオーバーライドする方法を見ることができますか? 適切にオーバーライドする方法について。super.clone() を呼び出して結果のオブジェクトをキャストした後、必要に応じてより深く複製できます。

暗黙のうちに、クローンの価値は、型の複雑で変更可能なフィールドの数が増えるにつれて減少します。

于 2011-03-11T23:10:21.570 に答える
1

cloneクローンをサポートすることを選択したオブジェクトごとに、何をするかが定義されています。Object.clone は保護されているため、誰かが明確に定義しない限り、オブジェクトの複製は許可されません。

于 2011-03-11T23:00:20.337 に答える
0

はい。

ただし、最初に、クラスが Cloneable を実装して例外をスローする必要があります

class A implements Cloneable{
    public int y;
    public B b;

    public A(){
        b = new B();
    }

    public static void main(String[] args) throws CloneNotSupportedException{
        A a = new A();
        A a2 = (A) a.clone();
        System.out.print(a.b==a2.b);
    }
}

出力: 真

于 2011-03-11T23:08:33.370 に答える