では次に、参照型の配列でシャローコピーとディープコピーの違いを体験できるミニアプリを作ってみます。
テーマは「生徒の成績をオブジェクトで管理してコピーする」です。
Java ミニアプリ例:シャローコピーとディープコピー体験
import java.util.Arrays;
class Student {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
// 表示用
public String toString() {
return name + "(" + score + ")";
}
}
public class StudentCopyApp {
public static void main(String[] args) {
// 1️⃣ 元の配列を作る
Student[] original = {
new Student("Alice", 80),
new Student("Bob", 70),
new Student("Charlie", 90)
};
// 2️⃣ シャローコピー(配列本体は別でも、中身は同じオブジェクト)
Student[] shallowCopy = Arrays.copyOf(original, original.length);
// 3️⃣ ディープコピー(中身も新しいオブジェクトにする)
Student[] deepCopy = new Student[original.length];
for (int i = 0; i < original.length; i++) {
deepCopy[i] = new Student(original[i].name, original[i].score);
}
// 4️⃣ コピー配列を変更
shallowCopy[0].score = 100; // シャローコピーは元にも影響
deepCopy[1].score = 95; // ディープコピーは元には影響なし
// 5️⃣ 結果を表示
System.out.println("=== 元の配列 ===");
System.out.println(Arrays.toString(original));
System.out.println("=== シャローコピー ===");
System.out.println(Arrays.toString(shallowCopy));
System.out.println("=== ディープコピー ===");
System.out.println(Arrays.toString(deepCopy));
}
}
Java実行結果のイメージ
=== 元の配列 ===
[Alice(100), Bob(70), Charlie(90)]
=== シャローコピー ===
[Alice(100), Bob(70), Charlie(90)]
=== ディープコピー ===
[Alice(80), Bob(95), Charlie(90)]
ポイント解説
- シャローコピー
Arrays.copyOfで作った配列は「配列の箱は別」ですが、中身のオブジェクトは同じものを参照しています。- だから
shallowCopy[0].score = 100とすると、original[0].scoreも 100 になってしまう。
- ディープコピー
- 新しいオブジェクトを作って配列に入れることで、元の配列と完全に独立させられる。
deepCopy[1].score = 95としてもoriginalには影響なし。
初心者向け覚え方
- 「配列コピーだけでは中身のオブジェクトまでは別物にならない」 → シャローコピー
- 「中身も新しいオブジェクトにする」 → ディープコピー
- 基本型はシャローコピーでも問題なし、オブジェクト型のときだけ注意。
