はじめに
Java Silver(SE 21対応)試験対策として、配列に関する問題を10問まとめました。配列の宣言・初期化の落とし穴、多次元配列、Arraysクラスの使い方など、試験で狙われやすいポイントを中心に構成しています。
問1 ⭐ 配列の宣言
次のうち、コンパイルエラーになるものはどれですか?
public class Main {
public static void main(String[] args) {
int[] a = new int[3]; // (1)
int b[] = new int[3]; // (2)
int[] c = new int[]; // (3)
int[] d = {1, 2, 3}; // (4)
}
}
A. (3)のみ
B. (2)と(3)
C. (3)と(4)
D. (2)のみ
解答と解説
正解: A
-
(1)
int[] a = new int[3];→ 要素数3の配列を生成。OK -
(2)
int b[] = new int[3];→ C言語スタイルの宣言。Javaでも有効。OK -
(3)
int[] c = new int[];→newで配列を生成する際はサイズの指定が必須。コンパイルエラー -
(4)
int[] d = {1, 2, 3};→ 配列初期化子。宣言と同時に使う場合はnew int[]を省略できる。OK
new int[]を使う場合はサイズ指定が必要ですが、初期化子{}を使う場合は要素数から自動的に決まるためサイズ指定は不要(指定するとエラー)です。
問2 ⭐ 配列のデフォルト値
次のコードの出力は何ですか?
public class Main {
public static void main(String[] args) {
int[] nums = new int[3];
boolean[] flags = new boolean[2];
String[] names = new String[2];
System.out.println(nums[0] + ", " + flags[0] + ", " + names[0]);
}
}
A. 0, false, null
B. 0, false, ""
C. null, null, null
D. コンパイルエラー
解答と解説
正解: A
配列の要素は自動的にデフォルト値で初期化されます。
| 型 | デフォルト値 |
|---|---|
int |
0 |
double |
0.0 |
boolean |
false |
char |
'\u0000' |
| 参照型 | null |
これはフィールド(インスタンス変数・クラス変数)のデフォルト値と同じです。ローカル変数と異なり、配列の要素は常にデフォルト値で初期化されます。
問3 ⭐⭐ 配列の代入と参照
次のコードの出力は何ですか?
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] a = {1, 2, 3};
int[] b = a;
b[0] = 99;
System.out.println(Arrays.toString(a));
}
}
A. [1, 2, 3]
B. [99, 2, 3]
C. [99, 99, 99]
D. コンパイルエラー
解答と解説
正解: B
int[] b = a;は配列のコピーではなく、参照のコピーです。aとbは同じ配列オブジェクトを指しています。
したがってb[0] = 99;で配列の最初の要素を変更すると、a[0]も99になります。
独立したコピーを作るにはArrays.copyOf()やclone()を使います。
int[] b = Arrays.copyOf(a, a.length); // 独立したコピー
int[] c = a.clone(); // 独立したコピー
問4 ⭐⭐ 多次元配列(ジャグ配列)
次のコードの出力は何ですか?
public class Main {
public static void main(String[] args) {
int[][] arr = new int[3][];
arr[0] = new int[]{1, 2};
arr[1] = new int[]{3, 4, 5};
arr[2] = new int[]{6};
System.out.println(arr.length);
System.out.println(arr[1].length);
}
}
A. 3と3
B. 3と2
C. 6と3
D. 3と5
解答と解説
正解: A
-
arr.length→ 外側配列の要素数は3 -
arr[1].length→arr[1]は{3, 4, 5}で要素数3
Javaの多次元配列は「配列の配列」であり、内側の配列はそれぞれ異なるサイズにできます(ジャグ配列)。new int[3][]は外側のサイズだけ指定し、内側は後から個別に設定しています。
なお、new int[][3]はコンパイルエラーになります。外側のサイズを先に指定する必要があります。
問5 ⭐⭐ ArrayIndexOutOfBoundsException
次のコードの実行結果は何ですか?
public class Main {
public static void main(String[] args) {
int[] arr = {10, 20, 30};
for (int i = 0; i <= arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
A. 10 20 30
B. 10 20 30 0
C. 10 20 30 の後にArrayIndexOutOfBoundsExceptionが発生
D. コンパイルエラー
解答と解説
正解: C
配列arrのサイズは3で、有効なインデックスは0〜2です。
ループ条件がi <= arr.length(i <= 3)なので、i=3のときにarr[3]にアクセスしようとし、ArrayIndexOutOfBoundsExceptionがスローされます。
i=0,1,2のときは正常に出力されるので、例外発生前に10 20 30 が出力されます。
正しくはi < arr.lengthとすべきです。この「off-by-one エラー」は非常に典型的な試験問題です。
問6 ⭐ Arrays.sort
次のコードの出力は何ですか?
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] arr = {5, 3, 8, 1, 4};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
A. [5, 3, 8, 1, 4]
B. [1, 3, 4, 5, 8]
C. [8, 5, 4, 3, 1]
D. コンパイルエラー
解答と解説
正解: B
Arrays.sort()は配列を昇順(自然順序) にソートします。元の配列が直接変更されます(新しい配列は生成されません)。
Arrays.toString()は配列の内容を[要素1, 要素2, ...]形式の文字列に変換します。
Arrays.sort()は破壊的メソッド(元の配列を変更する)であることに注意してください。
問7 ⭐⭐ Arrays.copyOf
次のコードの出力は何ですか?
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] original = {1, 2, 3};
int[] copy = Arrays.copyOf(original, 5);
System.out.println(Arrays.toString(copy));
}
}
A. [1, 2, 3]
B. [1, 2, 3, 0, 0]
C. [1, 2, 3, null, null]
D. ArrayIndexOutOfBoundsExceptionが発生
解答と解説
正解: B
Arrays.copyOf(original, newLength)は、元の配列を指定した長さでコピーします。
-
newLengthが元の配列より大きい場合、余った部分はデフォルト値で埋められる -
intのデフォルト値は0
元の配列{1, 2, 3}に対して長さ5を指定したため、[1, 2, 3, 0, 0]になります。
逆にnewLengthが元より小さい場合は、先頭から指定した長さ分だけコピーされます。
int[] short_copy = Arrays.copyOf(original, 2); // [1, 2]
問8 ⭐⭐⭐ 配列の共変性
次のコードの実行結果は何ですか?
public class Main {
public static void main(String[] args) {
String[] strings = {"A", "B", "C"};
Object[] objects = strings;
objects[0] = 123;
System.out.println(objects[0]);
}
}
A. 123
B. A
C. ArrayStoreExceptionが発生
D. コンパイルエラー
解答と解説
正解: C
Javaの配列は共変(covariant) です。String[]はObject[]のサブタイプとして扱えるため、Object[] objects = strings;はコンパイルが通ります。
しかし、実行時にはobjectsが実際にはString[]であることが記憶されています。objects[0] = 123;でIntegerを代入しようとすると、実行時型チェックによりArrayStoreExceptionがスローされます。
コンパイルは通るが実行時に例外が発生するパターンとして重要です。ジェネリクスのコレクション(List<String>をList<Object>に代入)ではこのような共変性は許可されません。
問9 ⭐⭐⭐ 多次元配列の初期化
次のコードの出力は何ですか?
public class Main {
public static void main(String[] args) {
int[][] arr = new int[2][3];
System.out.println(arr[0]);
System.out.println(arr[0][0]);
}
}
A. nullと0
B. [I@ハッシュコードと0
C. [0, 0, 0]と0
D. コンパイルエラー
解答と解説
正解: B
-
arr[0]:int[]型のオブジェクトです。printlnに配列を渡すとtoString()が呼ばれ、[I@に続くハッシュコードが表示されます([Iはint[]型を意味する内部表現) -
arr[0][0]:int型のデフォルト値0
new int[2][3]で生成した場合、外側配列の各要素(arr[0], arr[1])は自動的にnew int[3]で初期化されます。nullにはなりません。
配列の内容を見やすく表示するにはArrays.toString()やArrays.deepToString()を使います。
import java.util.Arrays;
System.out.println(Arrays.toString(arr[0])); // [0, 0, 0]
System.out.println(Arrays.deepToString(arr)); // [[0, 0, 0], [0, 0, 0]]
問10 ⭐⭐ 拡張for文と配列
次のコードの出力は何ですか?
public class Main {
public static void main(String[] args) {
int[] arr = {10, 20, 30};
for (int val : arr) {
val = val * 2;
}
for (int val : arr) {
System.out.print(val + " ");
}
}
}
A. 20 40 60
B. 10 20 30
C. 0 0 0
D. コンパイルエラー
解答と解説
正解: B
拡張for文の変数valは、配列要素のコピーです。valを変更しても元の配列には影響しません。
最初のループでval = val * 2;としていますが、これはローカル変数valを変更しているだけで、arrの要素は変更されていません。
配列の要素を変更するには、インデックスを使ってアクセスする必要があります。
for (int i = 0; i < arr.length; i++) {
arr[i] = arr[i] * 2; // これなら元の配列が変更される
}
参考
- Oracle Java SE 21 Language Specification - Chapter 10. Arrays
- Oracle Java SE 21 API - Arrays
- Oracle Java Tutorials - Arrays
@kotaro_ai_lab
AI活用や開発効率化について発信しています。フォローお気軽にどうぞ!