カテゴリ: Java 更新日: 2026/02/18

Javaの配列コピーを完全攻略!cloneやcopyOfで配列を複製する方法を徹底解説

Javaの配列のコピー方法まとめ(clone / Arrays.copyOf)
Javaの配列のコピー方法まとめ(clone / Arrays.copyOf)

先生と生徒の会話形式で理解しよう

生徒

「Javaで配列の内容を別の配列にコピーしたいのですが、単に代入するだけではダメなのでしょうか?」

先生

「実は、Javaの配列で変数同士をイコールで結んで代入すると、実体ではなく参照先がコピーされてしまうんです。つまり、片方を変えるともう片方も変わってしまいます。」

生徒

「それだと困りますね。元の配列を保護したまま、新しい配列として複製を作るにはどうすればいいですか?」

先生

「そんな時に使うのが、cloneメソッドやArrays.copyOfメソッドです。今回は初心者の方でも分かりやすく、配列のコピー方法を詳しく解説していきますね!」

1. Javaにおける配列のコピーとは

1. Javaにおける配列のコピーとは
1. Javaにおける配列のコピーとは

Javaプログラミングを学んでいると、データの集合を扱う「配列」に触れる機会が多くあります。配列を操作する中で、現在の配列の状態をそのまま保存しておきたい、あるいは別の変数として同じ内容の配列を新しく作りたいという場面が出てきます。これが「配列のコピー」です。

しかし、Javaの初心者の方が最初につまずきやすいポイントが、参照型としての配列の扱いです。基本データ型であるint型やdouble型などの変数であれば、単純に代入演算子を使うだけで値がコピーされます。一方で、配列はオブジェクトであるため、変数には「データがメモリ上のどこにあるか」という情報(参照)が格納されています。そのため、単純に代入を行うと、同じデータの実体を複数の変数が指し示すことになり、一見コピーされたように見えても、実体は共有されたままという現象が起きます。これを避けるためには、新しいメモリ領域を確保して中身を複製する「ディープコピー」に近い考え方や、標準メソッドの活用が必要になります。

2. cloneメソッドを使った最も簡単な配列の複製

2. cloneメソッドを使った最も簡単な配列の複製
2. cloneメソッドを使った最も簡単な配列の複製

Javaの配列には、自分自身の複製を作成するための「clone」というメソッドが標準で用意されています。これは最も直感的で短い記述で済むコピー方法です。cloneメソッドを呼び出すと、元の配列と同じ長さ、同じ要素を持つ新しい配列が生成されます。以下のプログラム例を見て、その挙動を確認してみましょう。


public class ArrayCloneExample {
    public static void main(String[] args) {
        // 元の配列を作成
        int[] originalArray = {10, 20, 30, 40, 50};
        
        // cloneメソッドを使って配列をコピー
        int[] copiedArray = originalArray.clone();
        
        // コピー先の値を変更してみる
        copiedArray[0] = 999;
        
        // 元の配列を表示
        System.out.print("Original: ");
        for (int value : originalArray) {
            System.out.print(value + " ");
        }
        
        // コピーした配列を表示
        System.out.print("\nCopied: ");
        for (int value : copiedArray) {
            System.out.print(value + " ");
        }
    }
}

Original: 10 20 30 40 50 
Copied: 999 20 30 40 50 

実行結果を見ると分かる通り、コピー先の配列の値を変更しても、元の配列には影響が出ていません。これは、cloneメソッドによって完全に新しい配列の領域が確保されたことを意味します。一次元配列のコピーであれば、この方法が非常に便利です。

3. Arrays.copyOfメソッドで柔軟にコピーする

3. Arrays.copyOfメソッドで柔軟にコピーする
3. Arrays.copyOfメソッドで柔軟にコピーする

Javaの標準ライブラリである「java.util.Arrays」クラスには、配列をコピーするための便利な静的メソッド「copyOf」が用意されています。このメソッドの最大の特徴は、コピーを作成すると同時に、新しい配列の長さを指定できる点にあります。元の配列より長く設定すれば後ろに初期値が詰められ、短く設定すれば途中で切り捨てられた配列が出来上がります。


import java.util.Arrays;

public class ArrayCopyOfExample {
    public static void main(String[] args) {
        String[] fruits = {"Apple", "Banana", "Cherry"};
        
        // 同じ長さでコピー
        String[] copy1 = Arrays.copyOf(fruits, fruits.length);
        
        // 元より長いサイズでコピー(新しい要素はnullになる)
        String[] copy2 = Arrays.copyOf(fruits, 5);
        
        // 元より短いサイズでコピー(先頭から指定数だけ抽出)
        String[] copy3 = Arrays.copyOf(fruits, 2);
        
        System.out.println("Copy1: " + Arrays.toString(copy1));
        System.out.println("Copy2: " + Arrays.toString(copy2));
        System.out.println("Copy3: " + Arrays.toString(copy3));
    }
}

Copy1: [Apple, Banana, Cherry]
Copy2: [Apple, Banana, Cherry, null, null]
Copy3: [Apple, Banana]

このように、Arrays.copyOfは単なる複製だけでなく、配列のリサイズ(サイズ変更)のような役割も兼ねることができます。実務では、動的に配列の大きさを拡張したい場合などによく利用される非常に実用的なメソッドです。引数には「コピー元」と「新しい長さ」を指定するだけなので、使い方も非常にシンプルです。

4. 多次元配列のコピーにおける注意点

4. 多次元配列のコピーにおける注意点
4. 多次元配列のコピーにおける注意点

ここで初心者が最も注意すべき点について解説します。それは「多次元配列」のコピーです。実は、先ほど紹介したcloneやArrays.copyOfは「シャローコピー(浅いコピー)」と呼ばれる動作をします。これは、配列の1段階目の要素は新しい配列としてコピーしますが、中身がさらに配列(多次元)であった場合、その内部の配列までは新しく作ってくれないという性質です。つまり、2次元配列に対してcloneを使っても、内側の配列への参照は共有されたままになってしまいます。これを解決するには、ループ処理を使って各行ごとにコピーを繰り返す必要があります。


import java.util.Arrays;

public class MultiDimensionalCopy {
    public static void main(String[] args) {
        int[][] original2D = {
            {1, 2, 3},
            {4, 5, 6}
        };
        
        // 2次元配列を正しくコピーする方法
        int[][] deepCopied2D = new int[original2D.length][];
        
        for (int i = 0; i < original2D.length; i++) {
            // 各行を個別にコピーする
            deepCopied2D[i] = original2D[i].clone();
        }
        
        // 値を変更して確認
        deepCopied2D[0][0] = 100;
        
        System.out.println("Original[0][0]: " + original2D[0][0]);
        System.out.println("Copied[0][0]: " + deepCopied2D[0][0]);
    }
}

Original[0][0]: 1
Copied[0][0]: 100

もし多次元配列に対して単純にcloneだけを行ってしまうと、内側の要素を変更した際に元の配列まで書き換わってしまうというバグの原因になります。複雑なデータ構造を扱う際は、どこまでが新しく生成され、どこが共有されているのかを常に意識することが重要です。

5. System.arraycopyによる高速な部分コピー

5. System.arraycopyによる高速な部分コピー
5. System.arraycopyによる高速な部分コピー

大量のデータを扱う際にパフォーマンスを重視するのであれば、「System.arraycopy」というメソッドも知っておくと良いでしょう。これはJavaのシステムが提供する非常に高速なコピー方法で、配列の特定の範囲だけを、別の既存の配列の指定した位置へ転送することができます。これまでのメソッドが「新しい配列を作る」ものだったのに対し、System.arraycopyは「既にある配列へデータを流し込む」という違いがあります。


public class SystemArrayCopyExample {
    public static void main(String[] args) {
        int[] source = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int[] destination = new int[10];
        
        // sourceのインデックス2から5個分を、destinationのインデックス3へコピー
        // 引数: (元, 元開始位置, 先, 先開始位置, 個数)
        System.arraycopy(source, 2, destination, 3, 5);
        
        System.out.print("Destination array content: ");
        for (int n : destination) {
            System.out.print(n + " ");
        }
    }
}

Destination array content: 0 0 0 3 4 5 6 7 0 0 

このメソッドはネイティブコードで実装されているため、ループを回して一つずつ代入するよりも遥かに高速に動作します。大規模なゲーム開発やデータ解析など、処理速度が求められる現場では重宝されます。引数が多いため最初は戸惑うかもしれませんが、「どの範囲を」「どこへ」持っていくかを厳密に指定できる強力なツールです。

6. 参照の代入と実体のコピーの違いを再確認

6. 参照の代入と実体のコピーの違いを再確認
6. 参照の代入と実体のコピーの違いを再確認

最後に、なぜここまで複数のコピー方法を紹介してきたのか、その根本的な理由を整理しましょう。プログラミング初心者の多くは、変数を「箱」として捉えますが、Javaの配列変数は「リモコン」のようなものです。変数Aを既存の配列Bに代入するという行為は、同じテレビ(配列の実体)を操作するリモコンをもう一つ増やす行為に過ぎません。これを知らずにプログラムを書くと、一つのリモコンでチャンネルを変えたら(値を変更したら)、もう一つのリモコンで見ている画面も変わってしまい、予測不能なエラーを引き起こします。

cloneやArrays.copyOfを使うということは、テレビそのものをもう一台新しく用意し、現在の番組設定をすべて反映させる作業です。これにより、片方の設定をどう変えても、もう片方には影響が出ないという独立性が保たれます。Javaで安全なコードを書くためには、この「参照」と「実体」の違いを理解し、適切なコピー手法を選択する能力が欠かせません。今回紹介した各メソッドは、用途に合わせて使い分けることで、バグの少ないクリーンなプログラム作成に大きく貢献してくれるはずです。

カテゴリの一覧へ
新着記事
New1
Micronaut
開発環境構築でつまずきやすいポイントまとめ!Micronautのエラーと対処法一覧
New2
Quarkus
QuarkusとGraalVMの進化を徹底解説!Javaネイティブイメージが切り拓く次世代開発の将来展望
New3
Micronaut
Micronaut + IntelliJ のプラグイン活用術!自動補完・テンプレート便利機能紹介
New4
Quarkus
QuarkusとGitHub Codespacesでクラウド開発を始める方法を完全解説!初心者でも迷わない開発環境構築ガイド
人気記事
No.1
Java&Spring記事人気No1
Java
Javaの配列とは?基本の使い方・宣言・初期化を初心者向けにわかりやすく解説
No.2
Java&Spring記事人気No2
Quarkus
Quarkus拡張開発を徹底解説!仕組みから自作エクステンションの作り方まで
No.3
Java&Spring記事人気No3
Java
Java ArrayListの使い方完全ガイド|追加・削除・取得・検索の基本操作
No.4
Java&Spring記事人気No4
Micronaut
MicronautのHTTPサーバー性能を最大化!初心者でもできるパフォーマンスチューニング
No.5
Java&Spring記事人気No5
Java
Javaの配列検索を完全攻略!値の探し方や多次元配列の条件一致を解説
No.6
Java&Spring記事人気No6
Java
Javaの型変換(キャスト)を徹底解説!暗黙的・明示的変換の違いを整理
No.7
Java&Spring記事人気No7
Java
Javaのコンパイルと実行の流れを解説!JVM・JDK・JREの違いも初心者向けに整理
No.8
Java&Spring記事人気No8
Quarkus
Quarkus拡張開発をマスター!ビルドプロセスの仕組みと内部構造を徹底解説