はじめに
Java Silver(SE 21対応)試験対策として、データ型・リテラル・変数に関する問題を10問まとめました。試験で頻出の引っかけポイントを中心に構成しています。
問1 ⭐ プリミティブ型の範囲
次のコードを実行すると、どうなりますか?
public class Main {
public static void main(String[] args) {
byte b = 128;
System.out.println(b);
}
}
A. 128
B. -128
C. 0
D. コンパイルエラー
解答と解説
正解: D
byteの範囲は-128〜127です。128はbyteに収まらないため、コンパイルエラーになります。
intリテラル128をbyte変数に代入しようとすると、コンパイラが範囲チェックを行い、範囲外であればエラーを出します。明示的キャストを使えば代入可能ですが、その場合はオーバーフローにより-128になります。
byte b = (byte) 128; // -128
問2 ⭐ リテラル表記
次のコードの出力は何ですか?
public class Main {
public static void main(String[] args) {
int a = 0b1010;
int b = 012;
int c = 0xA;
System.out.println(a + ", " + b + ", " + c);
}
}
A. 1010, 012, A
B. 10, 12, 10
C. 10, 10, 10
D. コンパイルエラー
解答と解説
正解: C
-
0b1010: 2進数リテラル → 1×8 + 0×4 + 1×2 + 0×1 = 10 -
012: 8進数リテラル(先頭が0)→ 1×8 + 2×1 = 10 -
0xA: 16進数リテラル → A = 10
すべて10進数で10になるため、出力は10, 10, 10です。
8進数リテラルは先頭に0を付ける表記で、意図せず使ってしまうことがあるので要注意です。
問3 ⭐⭐ アンダースコア区切りリテラル
次のうち、コンパイルエラーになるものはどれですか?
public class Main {
public static void main(String[] args) {
int a = 1_000_000; // (1)
double b = 3_.14; // (2)
long c = 0x1_0L; // (3)
int d = _100; // (4)
}
}
A. (2)のみ
B. (2)と(4)
C. (4)のみ
D. (1)と(3)
解答と解説
正解: B
数値リテラルのアンダースコアは以下の位置に置けません。
- リテラルの先頭または末尾
- 小数点の直前または直後
-
L/Fサフィックスの直前 -
0x/0bプレフィックスの直後
(2) 3_.14 → 小数点の直前にアンダースコアがあるためコンパイルエラー
(4) _100 → アンダースコアで始まるため数値リテラルではなく変数名として解釈されます。変数_100が未定義のためコンパイルエラー
(1) と (3) は正しい位置にアンダースコアがあるため問題ありません。
問4 ⭐ 浮動小数点リテラル
次のコードの出力は何ですか?
public class Main {
public static void main(String[] args) {
float f = 3.14;
System.out.println(f);
}
}
A. 3.14
B. 3.140000
C. 3
D. コンパイルエラー
解答と解説
正解: D
3.14はdoubleリテラルです。doubleからfloatへの暗黙的な型変換はできないため、コンパイルエラーになります。
正しくはFサフィックスを付けるか、明示的キャストが必要です。
float f1 = 3.14F; // OK
float f2 = (float) 3.14; // OK
問5 ⭐⭐ var(ローカル変数型推論)
次のコードのうち、コンパイルエラーになるものはどれですか?
public class Main {
public static void main(String[] args) {
var a = 10; // (1)
var b = "Hello"; // (2)
var c = null; // (3)
var d = new int[]{1}; // (4)
}
}
A. (3)のみ
B. (3)と(4)
C. (1)と(3)
D. すべて正常にコンパイルできる
解答と解説
正解: A
varは右辺から型を推論します。
-
(1)
var a = 10;→intと推論される。OK -
(2)
var b = "Hello";→Stringと推論される。OK -
(3)
var c = null;→nullだけでは型を推論できない。コンパイルエラー -
(4)
var d = new int[]{1};→int[]と推論される。OK
varは以下の場面では使用できません。
- 右辺が
nullのみ - メソッドの引数
- フィールド(インスタンス変数・クラス変数)
-
var自体を型名として使う(varは予約語ではなく予約された型名)
問6 ⭐⭐ 変数のスコープ
次のコードの出力は何ですか?
public class Main {
public static void main(String[] args) {
int x = 10;
for (int x = 0; x < 3; x++) {
System.out.print(x + " ");
}
System.out.println(x);
}
}
A. 0 1 2 10
B. 0 1 2 3
C. 10 10 10 10
D. コンパイルエラー
解答と解説
正解: D
mainメソッドのスコープで既にxが宣言されているため、同じスコープ内(forループはメソッドスコープの一部)で同名の変数を再宣言するとコンパイルエラーになります。
Javaでは、ローカル変数がスコープ内で既に宣言されている場合、そのスコープに含まれるブロック内で同名の変数を宣言することはできません。C言語等とは異なるので注意してください。
問7 ⭐ デフォルト値
次のコードの出力は何ですか?
public class Main {
static int a;
static boolean b;
static String c;
public static void main(String[] args) {
System.out.println(a + ", " + b + ", " + c);
}
}
A. 0, false, null
B. 0, false, ""
C. 0, true, null
D. コンパイルエラー
解答と解説
正解: A
クラス変数(staticフィールド)およびインスタンス変数は、明示的に初期化しなくてもデフォルト値が割り当てられます。
| 型 | デフォルト値 |
|---|---|
int |
0 |
boolean |
false |
参照型(String等) |
null |
double |
0.0 |
char |
'\u0000'(空文字) |
一方、ローカル変数にはデフォルト値がありません。初期化せずに使用するとコンパイルエラーになります。
問8 ⭐⭐ ローカル変数の初期化
次のコードの出力は何ですか?
public class Main {
public static void main(String[] args) {
int x;
if (args.length > 0) {
x = 1;
}
System.out.println(x);
}
}
A. 0
B. 1
C. 実行時の引数により0または1
D. コンパイルエラー
解答と解説
正解: D
ローカル変数xは、if文の条件がtrueの場合にのみ初期化されます。コンパイラは「確実に初期化される(definite assignment)」ことを保証できない場合、コンパイルエラーにします。
else句を追加して必ず初期化するか、宣言時に初期値を設定する必要があります。
int x;
if (args.length > 0) {
x = 1;
} else {
x = 0;
}
System.out.println(x); // OK
問9 ⭐⭐⭐ charとint
次のコードの出力は何ですか?
public class Main {
public static void main(String[] args) {
char c = 'A';
int i = c + 1;
char d = c + 1;
System.out.println(i);
System.out.println(d);
}
}
A. 66とB
B. BとB
C. 66と66
D. コンパイルエラー
解答と解説
正解: D
char c = 'A';は正常です('A'はUnicode値65)。
int i = c + 1; → c + 1はcharとintの演算で結果はint型(66)。int変数に代入するので問題ありません。
char d = c + 1; → c + 1の結果はint型です。intからcharへの暗黙的な縮小変換はできないため、コンパイルエラーになります。
正しくは明示的キャストが必要です。
char d = (char) (c + 1); // OK: 'B'
なお、char d = 'A' + 1; はコンパイルエラーになりません。コンパイル時定数の場合、値がcharの範囲内であれば暗黙的に縮小変換されます。変数cはコンパイル時定数ではない(final宣言されていない)ため、この最適化は適用されません。
問10 ⭐⭐⭐ varの制約
次のコードのうち、コンパイルエラーにならないものはどれですか?
import java.util.ArrayList;
public class Main {
var field = 10; // (1)
public void method(var param) { // (2)
// 処理
}
public static void main(String[] args) {
var list = new ArrayList<>(); // (3)
var i = 0; i = 1.0; // (4)
}
}
A. (3)のみ
B. (1)と(3)
C. (3)と(4)
D. すべてコンパイルエラー
解答と解説
正解: A
-
(1)
var field = 10;→varはフィールド宣言に使用できません。コンパイルエラー -
(2)
var param→varはメソッドの引数に使用できません。コンパイルエラー -
(3)
var list = new ArrayList<>();→varとダイヤモンド演算子<>の組み合わせは許可されています。型はArrayList<Object>と推論されます。コンパイル成功 -
(4)
var i = 0; i = 1.0;→var i = 0でiはint型と推論されます。int型の変数にdouble値1.0は代入できません。コンパイルエラー
varはローカル変数の宣言でのみ使用でき、一度推論された型は変更されません。
参考
- Oracle Java SE 21 Language Specification - Chapter 4. Types, Values, and Variables
- Oracle Java SE 21 Language Specification - Chapter 14. Blocks, Statements, and Patterns (14.4 Local Variable Declarations)
- Oracle Java Tutorials - Primitive Data Types
- JEP 286: Local-Variable Type Inference
@kotaro_ai_lab
AI活用や開発効率化について発信しています。フォローお気軽にどうぞ!