配列[Array]は、同じデータ型の複数の値を1つの変数に格納するためのデータ構造です。Javaにおける配列は固定長で、一度作成するとそのサイズを変更することはできないという特徴を持ちます。配列の各要素には、インデックス(添え字)を使ってアクセスし、インデックスは0から始まり、配列の長さ-1までの整数で表します。

整数を格納するための配列を例にして考えると、配列を使うことで複数の整数値を1つの変数にまとめて管理することができ、個々の値にアクセスしたり、変更したりするのが簡単になります。
// 整数型の配列を宣言して初期化 int[] numbers = {1, 2, 3, 4, 5}; // 配列の要素にアクセス System.out.println(numbers[0]); // 出力: 1 System.out.println(numbers[4]); // 出力: 5
↑は、numbers
という配列に5つの整数値を格納。numbers[0]
は配列の最初の要素(1)を、numbers[4]
は配列の最後の要素(5)を示しています。

ページ前半では、配列の基本的な使い方について解説します。後半では「そもそも配列とは何か?」「配列はオブジェクトである!」というような動作原理の基本を解説しますので、是非最後までご覧ください。
配列の宣言と初期化
Javaで配列を使うためには、①配列の宣言、②初期化というステップを踏む必要があります。ここでは、配列の宣言と初期化の基本的な方法についてご説明します。
配列の宣言
配列を宣言するというのは、配列の名前とそのデータ型をJavaに教えるということ。例えば、整数型の配列を宣言するには次のように書きます。
int[] numbers;

int
はデータ型を、[]
は配列であることを示しており、numbers
が配列の名前です。
配列の初期化
配列を宣言しただけでは、実際にデータを格納するためのメモリが割り当てられていません。データを格納するためには配列の初期化を行う必要があります。初期化にはいくつかの方法があります。
パターン1 サイズを指定して初期化
配列のサイズ(要素数)を指定して初期化する方法です。この方法では、配列の各要素はデフォルト値(整数の場合は0)で初期化されます。以下の方法で、5つの整数を格納できる配列 numbers
が作成されます。サイズは必ず指定しないといけません(指定しない場合コンパイルエラーが発生します)。
// 配列の宣言 int[] numbers; // 配列の初期化 numbers = new int[5];
パターン2 宣言と同時に初期化
配列を宣言すると同時に、初期化する方法もあります。この方法では、配列の各要素を具体的な値で初期化。以下の通りに記述すると、要素として1から5までの値を持つ配列 numbers
が作成されます。
int[] numbers = {1, 2, 3, 4, 5};

配列の宣言&初期化自体は難しくありません。以下のコードだけ頭に入っていればOK。
// 配列の宣言 int[] scores; // 配列の初期化 scores = new int[3]; // 3つの要素を持つ配列を初期化 // 宣言と同時に初期化 int[] ages = {18, 21, 25}; // 3つの値を持つ配列を作成
Javaの配列宣言では、[]
を型の後ろに書く方法と、変数名の後ろに書く方法の2種類があります。どちらでもコンパイルは通りますが、可読性やチームのコーディング規約によって推奨される方法が異なる場合があります。
型の後ろに []
を付ける例
int[] arrayA = new int[5]; String[] names = {"Alice", "Bob", "Carol"};
このように書くのが一般的で、配列であることが直感的にわかりやすいとされています。
変数名の後ろに []
を付ける例
int arrayB[] = new int[5]; String names2[] = {"Dave", "Ellen", "Frank"};
C言語由来の書き方で、Javaでも動作は同じですが、推奨されないことが多いです。
同じ行で複数の変数を宣言する場合の注意
int[] x, y; // xもyもint配列 int x2[], y2; // x2はint配列、y2はint型の変数
1行で複数変数を宣言するとき、どこに []
を付けるかで配列なのか通常の変数なのかが変わるので注意が必要です。

まとめとして、[]
は型の直後に書くのがわかりやすく、複数変数を1行で宣言するよりも1変数1行で宣言するほうが混乱を避けられます。
多次元配列
Javaでは、配列の中に配列を持つことができるため、複数の次元を持つ多次元配列を作成できます。最も一般的な多次元配列は二次元配列で、これは表やマトリックスのようなデータを扱うのに便利です。
二次元配列の宣言と初期化
二次元配列を宣言するには、次のように書きます。int
はデータ型を、[][]
は二次元配列であることを示しています。
int[][] matrix;
二次元配列についても初期化が必要です。考え方は通常の配列と同様です。
// 二次元配列の宣言 int[][] matrix; // 二次元配列の初期化 matrix = new int[2][3]; // 2行3列の二次元配列を作成 // 宣言と同時に初期化 int[][] scores = { {80, 90, 100}, {70, 85, 95} };
多次元配列を使うことで、表形式のデータや複雑なデータ構造を効率的に管理できるようになります。例えば、表形式のデータ(成績表など)やグリッド状のデータ(画像のピクセル情報など)を扱う場合に便利です。

二次元配列だけでなく、三次元以上の配列も作成できますが、使用する際には配列の次元が増えるほど管理が複雑になるため、適切な使い分けが必要です。
配列の要素へのアクセス
続けて、作成した配列に対する操作系を諸々ご説明します。基本的にどのような操作でも共通して、配列内の各要素にアクセスするためにはインデックス(添え字)を使用する、というのが基本ルールです。
要素の取得
配列の要素を取得するには、配列名の後に角括弧 []
を使い、取得したい要素のインデックスを指定します。
int[] numbers = {10, 20, 30, 40, 50}; int firstElement = numbers[0]; // 最初の要素(10) int thirdElement = numbers[2]; // 3番目の要素(30)
要素の設定
配列の要素を設定するには、同じく角括弧 []
を使って要素のインデックスを指定し、新しい値を代入します。
int[] numbers = {10, 20, 30, 40, 50}; numbers[1] = 25; // 2番目の要素を25に設定 numbers[4] = 55; // 5番目の要素を55に設定
二次元配列の要素へのアクセスと設定
二次元配列の要素にアクセスするには、行と列のインデックスを指定します。
// 宣言と同時に初期化 int[][] scores = { {80, 90, 100}, {70, 85, 95} }; // 要素へのアクセス int firstScore = scores[0][0]; // 1行目の1列目の要素(80) scores[1][2] = 99; // 2行目の3列目の要素を99に設定
配列の長さの取得
列の長さを取得するために length
プロパティを使用します。配列の長さは、その配列に含まれる要素の数を示します。
int[] numbers = {10, 20, 30, 40, 50}; int length = numbers.length; System.out.println("Array length: " + length); // 出力: Array length: 5
- Q二次元配列に対するlengthプロパティはどうなる?
- A
「配列の配列」であり、lengthフィールドは最初の次元、つまり「行数」を返します。以下の例で確認してください。
public class TwoDimensionalArrayExample { public static void main(String[] args) { int[][] array = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; // array.lengthは行数(外側の配列の長さ)を返す System.out.println("行数: " + array.length); // 3 // 各行の列数(内側の配列の長さ)は個別に取得する必要がある System.out.println("1行目の列数: " + array[0].length); // 3 System.out.println("2行目の列数: " + array[1].length); // 3 System.out.println("3行目の列数: " + array[2].length); // 3 } }
このように、二次元配列のlengthを直接指定すると、最初の次元のサイズ、すなわち行数が得られます。
配列のループ処理
配列の全ての要素にアクセスするために、forループや拡張forループ(foreachループ)を使います。
サンプルコード1 forループ
int[] numbers = {10, 20, 30, 40, 50}; System.out.println("Array elements (for loop):"); for (int i = 0; i < numbers.length; i++) { System.out.println("Element at index " + i + ": " + numbers[i]); } // 出力: // Element at index 0: 10 // Element at index 1: 20 // Element at index 2: 30 // Element at index 3: 40 // Element at index 4: 50
サンプルコード2 拡張forループ
int[] numbers = {10, 20, 30, 40, 50}; System.out.println("Array elements (foreach loop):"); for (int number : numbers) { System.out.println("Element: " + number); } // 出力: // Element: 10 // Element: 20 // Element: 30 // Element: 40 // Element: 50
参考 Javaのfor文:繰り返し処理の基本から応用までを3分で解説
配列のコピー
配列の内容を別の配列にコピーするには、Arrays.copyOf
メソッドを使用します。このメソッドは、元の配列の内容を指定された長さの新しい配列にコピーします。
int[] numbers = {10, 20, 30, 40, 50}; int[] numbersCopy = Arrays.copyOf(numbers, numbers.length); System.out.println("Copied array elements:"); for (int number : numbersCopy) { System.out.println("Element: " + number); } // 出力: // Element: 10 // Element: 20 // Element: 30 // Element: 40 // Element: 50
配列のソート
配列の要素を昇順に並べ替えるには、Arrays.sort
メソッドを使用します。
int[] numbers = {50, 20, 40, 10, 30}; Arrays.sort(numbers); System.out.println("Sorted array elements:"); for (int number : numbers) { System.out.println("Element: " + number); } // 出力: // Element: 10 // Element: 20 // Element: 30 // Element: 40 // Element: 50
配列の検索
特定の要素が配列内に存在するかどうかを調べるには、Arrays.binarySearch
メソッドを使用します。このメソッドを使用する前には、事前に配列をソートしておく必要があります。
int[] numbers = {10, 20, 30, 40, 50}; int index = Arrays.binarySearch(numbers, 30); if (index >= 0) { System.out.println("Element found at index: " + index); // 出力: Element found at index: 2 } else { System.out.println("Element not found"); } index = Arrays.binarySearch(numbers, 25); if (index >= 0) { System.out.println("Element found at index: " + index); } else { System.out.println("Element not found"); // 出力: Element not found }
配列の長さの取得、配列のループ処理、配列のコピー、配列のソート、配列の検索について詳しく解説しました。これらの操作を理解することで、Javaの配列を効果的に利用できるようになります。

ここまでがJavaにおける配列の基本知識。ここからは、より実践に即した形でJavaの配列をより深く深堀して解説します。
Javaの「配列」をより本質的に理解する
そもそも配列とは何か?を改めて深堀します。
「配列」とは、同じ型の要素を連続的に並べて管理するための仕組みです。低レイヤー言語(C言語など)を学習済の方であれば、メモリ上に要素が連続して並んでいるイメージを持つことができるかと思います。一方、Javaでは配列自体がオブジェクトとして扱われ、要素の型や長さを保持します。
配列はオブジェクトである
配列はオブジェクトである――このフレーズは、初心者の方には少し抽象的に感じられるかもしれません。ここで、なぜ「ただのデータ型」ではなく「オブジェクト」であると言えるのか、その違いを平易な言葉で解説します。
配列にも「住所(参照)」がある
Javaにおいて、オブジェクトとは「newによってヒープ領域に作られた実体」を指します(参考 オブジェクトとは?)。クラスのインスタンスと同じように、配列も new int[5]
のように書くと、Javaのヒープ領域に「配列オブジェクト」が確保され、そこへの参照(「住所」のようなもの)を変数が持つ仕組みです。
int x = 10;
のようにプリミティブ型(int, doubleなど)を使うときは、その値を直接変数に格納します。int[] arr = new int[5];
のように配列を使うときは、「配列の本体」はヒープ領域にあり、arr
という変数は配列の本体がある「場所」を指し示すだけです。
「ただのデータ型」のように考えると、「配列変数に入っているのは配列そのもの」だと誤解しがちですが、実際には「配列そのものが置かれている場所への参照」が入っている点が大きな違いです。
length
という情報を持っているという意味
配列はオブジェクトであるので、「要素数」や「要素の型」といった情報を内部に持つことができています。たとえば、arr.length
という形で要素数を取得することができます。これは「配列オブジェクト」が自分が何個の要素を持っているのかを覚えているからです。
int[] arr = new int[5]; System.out.println(arr.length); // 5 と出力
もし「配列」が本当にただの「数字のかたまり」や「型」だけであれば、こうしたメタ情報(要素数など)を持ち歩くことは難しいでしょう。オブジェクトとして扱われるからこそ、length
という変数を備え、範囲外アクセスをチェックしたりできる仕組みが成り立っています。
instanceof 演算子や Object 型との関係
Javaのすべてのオブジェクトは、最終的に Object
クラスを親に持つとされます。配列も例外ではなく、実は
int[] arr = new int[5]; System.out.println(arr instanceof Object); // true
のように、「配列は Object
のインスタンス」として判定されます。これは、配列が特殊なクラスのインスタンスとして実装されていることを意味します。もし単なる「データ型」扱いであれば、instanceof Object
が通ることはありません。
参考 インデックスの範囲チェック
Javaでは、配列のアクセス時に必ずインデックスが範囲内かどうかチェックされます。範囲外の場合(0 <= index < arr.length
を外れる)は ArrayIndexOutOfBoundsException
がスローされ、安全性が担保されています。
int[] arr = {1, 2, 3}; System.out.println(arr[3]); // ArrayIndexOutOfBoundsException
参考 共変(Covariance)と型安全性
Javaの配列は「共変」という性質を持ち、例えば Number[] nums = new Integer[5];
のように、親クラス型の配列参照に子クラス型の配列オブジェクトを格納できます。しかし、実際の格納先は Integer[]
なので、子クラスの要素以外を代入しようとすると実行時に ArrayStoreException
が発生します。
Number[] nums = new Integer[5]; nums[0] = 10; // IntegerなのでOK nums[1] = 10.5; // Doubleを代入しようとするとArrayStoreException
配列型変数 / 配列インスタンス / 要素 の区別を明確にする

最後に復習を兼ねて、配列型変数と配列インスタンス、要素の違いを改めて整理しておきましょう。
配列型変数
- イメージ:
配列型変数は、配列そのものを指し示す「ラベル」のようなものです。 - 説明:
- この変数は、配列そのもの(箱)の場所を記憶します。
- 例えば、
int[] scores;
と書くと、scores
という名前の箱を使う準備をしていることになりますが、まだ中身は作られていません。
配列インスタンス
- イメージ:
配列インスタンスは、実際に作られた「箱」です。 - 説明:
new
キーワードを使って実際の配列(箱)を作ります。- 例えば、
scores = new int[5];
とすると、5個の数字を入れられる箱が作られ、その箱の場所がscores
に記憶されます。
要素
- イメージ:
要素は、その箱の中に入っている「一つ一つの中身」です。 - 説明:
- 箱の中には、数字や文字などのデータが入ります。
- たとえば、
scores[0]
は箱の中の最初の場所に入っている数字を意味し、scores[1]
は2番目の場所の数字を指します。
// 1. 配列型変数の宣言(箱を使うためのラベルを作る) int[] scores; // 2. 配列インスタンスの生成(実際の箱を作る) scores = new int[5]; // 数字を5個入れる箱が作られる // 3. 要素へのアクセス(箱の中のそれぞれの場所に数字を入れる) scores[0] = 90; // 最初の場所に90を入れる scores[1] = 80; // 次の場所に80を入れる // ... scores[2], scores[3], scores[4] にも必要な数字を入れる
このように、
- 配列型変数 は箱の「ラベル」、
- 配列インスタンス は実際に作られた「箱」、
- 要素 はその箱の中に入る「一つ一つのデータ」と考えると、Javaの配列がどういう仕組みになっているかが分かりやすいと思います。
配列のまとめ
もし「配列はただのデータ型」と考えると、
- 変数に格納されているのは「配列の中身」そのものだと思い込んでしまう
- 配列を別変数に代入したら、配列が複製されたと思い込んでしまう
などの誤解を招きやすいです。
しかし実際には、クラスのインスタンスと同じく、newによって作られた一つのまとまりを「アドレスを通じて参照している」状態です。こうした違いを理解すると、配列の挙動がより納得しやすくなるでしょう。