Java | 基礎文法:配列の宣言

Java Java
スポンサーリンク

配列宣言の全体像

配列は「同じ型の要素を並べて管理する入れ物」です。Java の配列は「長さが固定」「0 始まりの添字」「参照型(配列そのものはオブジェクト)」という3点が基本です。宣言は「型+角括弧+変数名」で行い、必要に応じてサイズ(長さ)や初期値を同時に指定します。


宣言だけ/宣言と生成/宣言と初期化の違い

宣言だけ(まだ何も入っていない)

int[] a;      // int の配列「への参照」を宣言。まだ配列は存在しない(null)
String[] s;   // String の配列「への参照」
Java

「配列変数」は配列オブジェクトへの参照です。宣言だけでは実体がないため、使う前に「生成(new)」が必要です。

宣言して生成(サイズを決める)

int[] a = new int[3];   // 要素数 3 の int 配列を生成(初期値は 0)
String[] s = new String[2]; // 要素数 2 の String 配列(初期値は null)
Java

new 型[長さ] で配列オブジェクトが作られます。「長さは固定」で、後から増減できません。

宣言して初期化(リテラルで値を並べる)

int[] a = {10, 20, 30};          // 要素数は並べた数で決まる
String[] s = {"Java", "is", "fun"};
Java

「並べた通りに値が入る」最も読みやすい書き方です。サイズ指定と要素列挙は同時には書けません(new int[3]{...} のような記法は不可)。


重要ポイントの深掘り:型・初期値・長さの不変

型は要素ごとに統一

配列の型は要素の型と一致します。int[] に小数や文字列は入れられません。ラッパー型(Integer[])とプリミティブ(int[])は別物です。

int[] nums = new int[3];
nums[0] = 42;      // OK
// nums[1] = "hi"; // NG:型が違う
Java

デフォルト初期値

  • 数値(int, long, double など):0
  • boolean:false
  • 参照型(String, Object など):null
boolean[] flags = new boolean[2]; // {false, false}
String[] names = new String[2];   // {null, null}
Java

「未代入でも何かは入っている」ため、ヌルチェックと値チェックを使い分けます。

長さは不変(後から増えない)

int[] a = new int[3];
// a.length = 5; // NG:length は読み取り専用
Java

増やしたい場合は「新しい配列を作ってコピー」するか、可変長の ArrayList を使いましょう。


宣言位置と書き方のスタイル

推奨スタイル:角括弧は型側

int[] a;    // 推奨
// int a[]; // 旧来の記法。意味は同じだが、型側に[]を付けるほうが読みやすい
Java

チーム規約がなければ「型側に []」で統一すると、複合宣言のときにも誤読が減ります。

参照の共有と代入

int[] a = {1, 2};
int[] b = a;       // 同じ配列を指す(参照のコピー)
b[0] = 99;
System.out.println(a[0]); // 99(共有しているので両方に見える)
Java

「独立したコピー」が必要なら、Arrays.copyOfclone を使います。

int[] a = {1, 2, 3};
int[] c = a.clone();               // 新しい配列
int[] d = java.util.Arrays.copyOf(a, a.length);
Java

多次元配列(配列の配列)

宣言と生成

int[][] m;                 // 2 次元配列への参照
m = new int[2][3];         // 2 行 3 列(行×列)
m[0][1] = 42;
Java

「配列の配列」なので、行ごとに長さを変えるジャグ配列も作れます。

int[][] jag = new int[3][];
jag[0] = new int[1];
jag[1] = new int[2];
jag[2] = new int[4];
Java

初期化リテラル

int[][] m = {
    {1, 2, 3},
    {4, 5, 6}
};
Java

行ごとの括弧で「見た目通り」に宣言・初期化できます。


宣言と同時初期化の応用

要素が多い場合の読みやすさ

String[] langs = {
    "Java", "Kotlin", "Scala",
    "Groovy", "Clojure"
};
Java

改行を使って「ひと目で分かる」形にします。保守しやすさが上がります。

new とブロック初期化の組み合わせ(メソッド引数向け)

printAll(new String[] {"A", "B", "C"});

static void printAll(String[] arr) {
    for (String s : arr) System.out.println(s);
}
Java

「その場で一時配列を作って渡す」パターンは、テストコードやユーティリティに便利です。


よくある落とし穴と対策

Null のまま使って例外

int[] a;               // まだ null
// a[0] = 1;           // NullPointerException
a = new int[1];        // 生成してから使う
a[0] = 1;
Java

「宣言だけでは配列は存在しない」。必ず new か初期化リテラルで生成します。

添字範囲外アクセス

int[] a = {10, 20, 30};
// a[3] = 0;          // ArrayIndexOutOfBoundsException(最後は a.length-1)
Java

ループ条件は「未満(i < a.length)」を徹底して、オフバイワンを防ぎます。

プリミティブ配列とラッパー配列の取り違え

int[] p = {1, 2};        // プリミティブ
Integer[] w = {1, 2};    // ラッパー(null を持てる、ジェネリクスと相性)
Java

API がどちらを要求しているか確認しましょう。List<Integer> とは直接互換ではありません。


実用例で身につける

例 1: 宣言・生成・代入を段階で

public class DeclStep {
    public static void main(String[] args) {
        int[] scores;               // 宣言
        scores = new int[3];        // 生成(長さ 3)
        scores[0] = 80;             // 代入
        scores[1] = 90;
        scores[2] = 75;
        System.out.println(scores[1]); // 90
    }
}
Java

例 2: 初期化リテラルで一気に

public class InitLiteral {
    public static void main(String[] args) {
        String[] fruits = {"apple", "banana", "cherry"};
        for (int i = 0; i < fruits.length; i++) {
            System.out.printf("[%d]=%s%n", i, fruits[i]);
        }
    }
}
Java

例 3: 多次元配列の宣言・初期化

public class Matrix {
    public static void main(String[] args) {
        int[][] m = {
            {1, 2, 3},
            {4, 5, 6}
        };
        System.out.println(m[1][2]); // 6
    }
}
Java

設計の指針(重要部分のまとめ)

  • 配列変数は「参照」。宣言だけでは null、使う前に必ず生成(new)か初期化リテラルで実体化。
  • 長さは固定。増やす必要があるなら新しい配列へコピー、頻繁に増減するなら ArrayList を選ぶ。
  • ループの条件は「未満(i < arr.length)」でオフバイワンを防ぐ。多次元は「配列の配列」として捉える。
  • デフォルト初期値(数値0、boolean false、参照 null)を理解し、ヌル扱いと値扱いを正しく設計。
  • 参照を共有すると両者に変更が見える。独立性が必要なら clone/copyOf を使う。

タイトルとURLをコピーしました