17
int[][] array = new int[][] {...}
int[][] clone = array.clone();

私は素朴にこれがうまくいくと思っていました。しかし、そうではありませんでした。最初の次元のみが複製されました。真の複製が必要な場合は、他の次元を手動で複製する必要がありました。注: 内容は適切にコピーされました。しかし、私が変更したときclone[0][1]、それはに反映されましたarray[0][1]

そして.clone()、浅いクローンを実行することが知られていますint[][]が、単一のオブジェクトのように見えます (少なくともその内部実装がわからない場合)

なぜその行動が選ばれるのですか?int[][]配列の最初の次元だけでなく、配列オブジェクトを参照していませんか? また、最初の次元のみを複製すると、どのようなシナリオで望ましい動作が得られるのでしょうか?

4

4 に答える 4

8

なぜその行動が選ばれるのですか?

一貫性、おそらく。

あなたが言うようにint[][]、配列オブジェクトを参照します。たまたま、各配列要素の内容が別の配列になっていることがありますが、それは単なる詳細です。Java はすべての配列を同じように複製します。要素は任意の型である可能性があるため、ディープ コピーの実行を保証することはできません。

したがってclone()、配列は浅いコピーを実行するため、最初の次元のみが複製されます。

(一般に、クローンが深いコピーを意味するか浅いコピーを意味するかという質問に対して、単一の「最良の」または「明白な」答えはないようです。開発者が望むものは、各フィールドがアプリケーションによってどのように使用されているかによって異なります。したがって、画一的なアプローチには当然限界があります。)

于 2013-04-24T07:41:24.470 に答える
3

真の多次元配列がないため、この動作が示されます。

Java は、配列の配列を作成することによって多次元を実現します。つまり:

int[][] is actually Array<Array<int>>

したがって、クローンは最初の次元のみをコピーします。

3 次元配列を試していた場合は、3 回複製する必要があります。

于 2013-04-24T07:41:36.187 に答える
1

このcloneメソッドは、いわゆる浅いコピーです (メソッドに関する別のスタックオーバーフローの回答をclone参照)。つまり、すべての要素が参照によってコピーされます。

必要なものを取得するには (ディープ クローニングとも呼ばれます)、Arrays.copy再帰的にすべての配列を自分でコピーして、見つかったすべての (サブ) 配列がディープ クローンを取得するか、このスタックオーバーフローの回答をディープ クローニングで確認します。

ハッピーハッキング:-)

于 2013-04-24T07:43:55.910 に答える