参照型の配列では、各要素に入っているのは参照です。通常の方法で配列を複製した場合は、新たな配列は作成されますが、その中に入っている参照は、元の配列と同じオブジェクト(本体)を指しています。
こういったコピーのことを「シャローコピー」(浅いコピー)と呼びます。
┏━配列a1━━━━━━━━━━━━━━━━┓ ┃┏━━━┓┏━━━┓┏━━━┓┏━━━┓┃ ┃┃参 照┃┃参 照┃┃参 照┃┃参 照┃┃ ┃┗━━━┛┗━━━┛┗━━━┛┗━━━┛┃ ┃ : : : : ┃ ┗━━:━━━━:━━━━:━━━━:━━┛ : : : : ┏配列━┓┏配列━┓┏配列━┓┏配列━┓ ┃┏━┓┃┃┏━┓┃┃┏━┓┃┃┏━┓┃ ┃┃ 0┃┃┃┃ 2┃┃┃┃ 4┃┃┃┃ 6┃┃ ┃┗━┛┃┃┗━┛┃┃┗━┛┃┃┗━┛┃ ┃┏━┓┃┃┏━┓┃┃┏━┓┃┃┏━┓┃ ┃┃ 1┃┃┃┃ 3┃┃┃┃ 5┃┃┃┃ 7┃┃ ┃┗━┛┃┃┗━┛┃┃┗━┛┃┃┗━┛┃ ┗━━━┛┗━━━┛┗━━━┛┗━━━┛ : : : : ┏━━:━━━━:━━━━:━━━━:━━┓ ┃ : : : : ┃ ┃┏━━━┓┏━━━┓┏━━━┓┏━━━┓┃ ┃┃参 照┃┃参 照┃┃参 照┃┃参 照┃┃ ┃┗━━━┛┗━━━┛┗━━━┛┗━━━┛┃ ┗━配列a2━━━━━━━━━━━━━━━━┛
シャローコピーに対して、内部から参照しているオブジェクト(本体)を、全て複製して新たに配列に格納する方法を、「ディープコピー」(深いコピー)と呼びます。
┏━配列a1━━━━━━━━━━━━━━━━┓ ┃┏━━━┓┏━━━┓┏━━━┓┏━━━┓┃ ┃┃参 照┃┃参 照┃┃参 照┃┃参 照┃┃ ┃┗━━━┛┗━━━┛┗━━━┛┗━━━┛┃ ┃ : : : : ┃ ┗━━:━━━━:━━━━:━━━━:━━┛ : : : : ┏配列━┓┏配列━┓┏配列━┓┏配列━┓ ┃┏━┓┃┃┏━┓┃┃┏━┓┃┃┏━┓┃ ┃┃ 0┃┃┃┃ 2┃┃┃┃ 4┃┃┃┃ 6┃┃ ┃┗━┛┃┃┗━┛┃┃┗━┛┃┃┗━┛┃ ┃┏━┓┃┃┏━┓┃┃┏━┓┃┃┏━┓┃ ┃┃ 1┃┃┃┃ 3┃┃┃┃ 5┃┃┃┃ 7┃┃ ┃┗━┛┃┃┗━┛┃┃┗━┛┃┃┗━┛┃ ┗━━━┛┗━━━┛┗━━━┛┗━━━┛ ┏配列━┓┏配列━┓┏配列━┓┏配列━┓ ┃┏━┓┃┃┏━┓┃┃┏━┓┃┃┏━┓┃ ┃┃ 0┃┃┃┃ 2┃┃┃┃ 4┃┃┃┃ 6┃┃ ┃┗━┛┃┃┗━┛┃┃┗━┛┃┃┗━┛┃ ┃┏━┓┃┃┏━┓┃┃┏━┓┃┃┏━┓┃ ┃┃ 1┃┃┃┃ 3┃┃┃┃ 5┃┃┃┃ 7┃┃ ┃┗━┛┃┃┗━┛┃┃┗━┛┃┃┗━┛┃ ┗━━━┛┗━━━┛┗━━━┛┗━━━┛ : : : : ┏━━:━━━━:━━━━:━━━━:━━┓ ┃ : : : : ┃ ┃┏━━━┓┏━━━┓┏━━━┓┏━━━┓┃ ┃┃参 照┃┃参 照┃┃参 照┃┃参 照┃┃ ┃┗━━━┛┗━━━┛┗━━━┛┗━━━┛┃ ┗━配列a2━━━━━━━━━━━━━━━━┛
ディープコピーは、各要素を複製する手順を踏まなければなりません。
int[][] a1 = { {0, 1}, {2, 3}, {4, 5}, {6, 7} }; int len1 = a1.length; int[][] a2 = new int[len1][]; for (int i = 0; i < len1; i ++) { int len2 = a1[i].length; a2[i] = new int[len2]; for (int j = 0; j < len2; j ++) { a2[i][j] = a1[i][j]; } }
int[][] a1 = { {0, 1}, {2, 3}, {4, 5}, {6, 7} }; int[][] a2 = a1.clone(); for (int i = 0; i < a1.length; i ++) { a2[i] = a1[i].clone(); }
また、基本型のデータでは、参照ではなく値が直接入っているので、シャローコピー、ディープコピーの区別はありません。