11

私は最終クラスを持っていNameAndValueます。を使用してオブジェクトの配列をコピーしました。コピーした配列のNameAndValueオブジェクトをSystem.arrayCopy()変更するとNameAndValue、元の配列に反映されます。

public final class NameAndValue {
    public String name;
    public String value;

    public NameAndValue() { }

    public NameAndValue(String name, String value) {
        this.name = name;
        this.value = value;
    }
}
public class Main {
    public static void main(String[] args) {
        NameAndValue[] nv = new NameAndValue[4];
        nv[0] = new NameAndValue("A", "1");
        nv[1] = new NameAndValue("B", "2");
        nv[2] = new NameAndValue("C", "3");
        nv[3] = new NameAndValue("D", "4");

        NameAndValue[] nv2 = new NameAndValue[4];
        System.arraycopy(nv, 0, nv2, 0, 2);
        nv2[2] = new NameAndValue("Y", "25");
        nv2[3] = new NameAndValue("Z", "26");

        for (int i = 0; i < 2; i++) {
            NameAndValue[] nv3 = new NameAndValue[4];
            System.arraycopy(nv2, 0, nv3, 0, 4);
            nv3[2].value = String.valueOf(i);
            nv3[3].value = String.valueOf(i + 1);

            System.out.println(nv2[2].value);
            System.out.println(nv2[3].value);
            System.out.println("-----------------------");
        }
    }
}

次のような出力が得られます。

0
1
-----------------------
1
2
-----------------------

すべてのケースで 25 と 26 として出力されるはずですよね?? なんで変わるの??

4

6 に答える 6

22

System.arrayCopy()は、オブジェクトまたはオブジェクトへの参照をコピーしますか?

参考までに、それは浅いコピーです。驚いたことに、ドキュメントは、参照するものを再帰的にコピーするのではなく、配列要素のコピーについてのみ説明しているため、明示的には言及していません。

これを持っている場合とまったく同じです:

NameAndValue nv1 = new NameAndValue("A", "1");
NameAndValue nv2 = nv1;
nv2.value = "4";
System.out.println(nv1.value); // 4

各配列要素は、上記のnv1およびnv2変数のようなものです。同じ基になるオブジェクトnv1nv2参照(ポイント)するのと同じように、配列エントリも、ある配列から別の配列にコピーされる場合を含めて実行します。

于 2013-02-28T12:06:00.667 に答える
2

両方の配列が同じ基になるオブジェクトを参照しているため、変更されます。配列内の位置に新しいオブジェクトを割り当てることができ、それは他の配列には反映されませんが、両方の配列が指しているオブジェクトに変更を加えると、両方で異なるように見えます.

この意味では、厳密に参照渡しではなく、「値による参照」を渡しますが、参照が同じままであるため、表示される効果があります。

このようなコピーは、特に明記されていない限り、Java ではほとんど常に浅いコピーです。これも例外ではありません。

于 2013-02-28T12:05:13.040 に答える
1

System.arraycopy は浅いコピーです。理由は次のとおりです。

JNI を使用して memcpy() のようなものを使用し、ポインタをメモリにコピーします。それは非常に高速な操作です。

于 2013-12-03T20:31:40.937 に答える
1

As far as I know arraycopy is a shallow copy. Which means the new array will reference to the addresses of the elements in the old array. So if you adjust a value in one of them, it will reflect on both

于 2013-02-28T12:09:00.677 に答える
0
int[] a = {1, 2, 3};
int[] b = new int[3];
System.arraycopy(a, 0, b, 0, 3);
b[1] = 0;
System.out.println(Arrays.toString(b));
System.out.println(Arrays.toString(a));

出力は次のようになります。

[1, 0, 3]
[1, 2, 3]
于 2016-08-12T02:44:29.477 に答える