web-dev-qa-db-ja.com

Java配列のクローンメソッド

Javaのclone()メソッドは、配列で使用されたときに正確に何を返しますか?元からコピーされたデータを含む新しい配列を返しますか?

例:

int[] a = {1,2,3};
int[] b = a.clone();
56
Bunsen McDubbs

cloneメソッドが配列に対して呼び出されると、ソース配列と同じ要素を含む(または参照する)新しい配列への参照を返します。

したがって、あなたの例では、int[] aはヒープ上に作成された別個のオブジェクトインスタンスであり、int[] bはヒープ上に作成された別個のオブジェクトインスタンスです。 (すべての配列はオブジェクトであることを忘れないでください)。

    int[] a = {1,2,3};
    int[] b = a.clone();

    System.out.println(a == b ? "Same Instance":"Different Instance");
    //Outputs different instance

int[] bを変更した場合、2つは別個のオブジェクトインスタンスであるため、変更はint[] aに反映されません。

    b[0] = 5;
    System.out.println(a[0]);
    System.out.println(b[0]);
    //Outputs: 1
    //         5

これは、ソース配列にオブジェクトが含まれる場合、少し複雑になります。 cloneメソッドは、ソース配列と同じオブジェクトを参照する新しい配列への参照を返します。

クラスDog...がある場合.

    class Dog{

        private String name;

        public Dog(String name) {
            super();
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

    }

そして、タイプDog...の配列を作成して入力します.

    Dog[] myDogs = new Dog[4];

    myDogs[0] = new Dog("Wolf");
    myDogs[1] = new Dog("Pepper");
    myDogs[2] = new Dog("Bullet");
    myDogs[3] = new Dog("Sadie");

その後、犬をクローン...

    Dog[] myDogsClone = myDogs.clone();

配列は同じ要素を参照しています...

    System.out.println(myDogs[0] == myDogsClone[0] ? "Same":"Different");
    System.out.println(myDogs[1] == myDogsClone[1] ? "Same":"Different");
    System.out.println(myDogs[2] == myDogsClone[2] ? "Same":"Different");
    System.out.println(myDogs[3] == myDogsClone[3] ? "Same":"Different");
    //Outputs Same (4 Times)

つまり、複製された配列を介してアクセスするオブジェクトを変更した場合、同じ参照を指すため、ソース配列の同じオブジェクトにアクセスすると、変更が反映されます。

    myDogsClone[0].setName("Ruff"); 
    System.out.println(myDogs[0].getName());
    //Outputs Ruff

ただし、配列自体への変更は、その配列にのみ影響します。

    myDogsClone[1] = new Dog("Spot");
    System.out.println(myDogsClone[1].getName());
    System.out.println(myDogs[1].getName());
    //Outputs Spot
    //        Pepper

オブジェクト参照がどのように機能するかを一般的に理解している場合、オブジェクトの配列がクローン作成および変更によってどのように影響を受けるかを簡単に理解できます。参照とプリミティブに関するさらなる洞察を得るために、この素​​晴らしい 記事 を読むことをお勧めします。

ソースコードの要点

83
Kevin Bowersox

clone()メソッドは、このオブジェクトのコピーを作成して返します。 「コピー」の正確な意味は、オブジェクトのクラスに依存する場合があります。一般的な目的は、任意のオブジェクトxについて、式:

_ x.clone() != x
_

真実であり、その表現は:

_ x.clone().getClass() == x.getClass()
_

本当ですが、これらは絶対的な要件ではありません。

通常は次のような場合です:

_ x.clone().equals(x)
_

これは絶対条件ではありません。

慣例により、返されるオブジェクトは_super.clone_を呼び出して取得する必要があります。クラスとそのすべてのスーパークラス(Objectを除く)がこの規則に従う場合、x.clone().getClass() == x.getClass()になります。

3
9ine