ラッパークラス(オートボクシング/アンボクシングとNullPointerException)難易度 高無料
次のコードと、ラッパークラスの一般的な挙動について、次の4つの記述のうち正しいものをすべて選べ。
1 public class Q19 {
2 public static void main(String[] args) {
3 Integer x = null;
4 int y = x + 1;
5 System.out.println(y);
6 }
7 }
A 4行目 int y = x + 1; の実行時、null であるラッパー参照をアンボクシングしようとして NullPointerException がスローされる。 B int と Integer の混在した演算(例:int + Integer)では、自動アンボクシングにより Integer 側が int に変換されてから演算される。 C Integer 同士を == で比較すると、値さえ等しければキャッシュ範囲に関わらず常に true になる。 D オートボクシング(int → Integer)は、明示的な new Integer(...) 呼び出しと完全に同じ経路(常に新規オブジェクトを生成)で行われる。
- A4行目
int y = x + 1;の実行時、nullであるラッパー参照をアンボクシングしようとしてNullPointerExceptionがスローされる。 - B
intとIntegerの混在した演算(例:int + Integer)では、自動アンボクシングによりInteger側がintに変換されてから演算される。 - C
Integer同士を==で比較すると、値さえ等しければキャッシュ範囲に関わらず常にtrueになる。 - Dオートボクシング(
int → Integer)は、明示的なnew Integer(...)呼び出しと完全に同じ経路(常に新規オブジェクトを生成)で行われる。
正解・解説・誤答理由・ひっかけを見る▼ open
✓ 正解:AAI作成・独立検証済
解説
- A:正しい。
xはnull。x + 1の演算ではxをintにアンボクシングする必要があるが、参照先が無いためNullPointerExceptionが実行時にスローされる(コンパイルエラーではない=コンパイル自体は通る)。 - B:正しい。
intとIntegerが混在する算術演算では、Integer側が自動的にアンボクシングされてint同士の演算になる。 - C:誤り。
==はラッパーオブジェクトの参照を比較する演算子であり、-128〜127のキャッシュ範囲外では別オブジェクトになりfalseになり得る。「常に true」は誤り。 - D:誤り。オートボクシングは内部的に
Integer.valueOf(int)を呼び出す。valueOfはキャッシュ範囲内なら既存オブジェクトを再利用するため、常に新規オブジェクトになるわけではない(new Integer(...)は常に新規生成するが、それとオートボクシングの経路は同じではない)。
したがって正しいのは A・B。
- C
==は参照比較。-128〜127のキャッシュ範囲外では値が同じでも別オブジェクトになりfalseになり得る。値の比較にはequalsを使う。「常に true」は誤り。 - Dオートボクシングは内部で
Integer.valueOf(int)を呼び出し、キャッシュ範囲内なら既存オブジェクトを再利用する。常に新規生成するnew Integer(...)とは経路も挙動も異なる。
ひっかけ: 「アンボクシングに失敗するのはコンパイルエラーだろう」という誤解、および「オートボクシング=
new Integer() と同じ」という誤解の2点が典型的な罠。前者は実行時例外(NullPointerException)、後者はvalueOf によるキャッシュ再利用が絡む点で異なる。コマンド例と想定される挙動(未実行)
実行結果:
Exception in thread "main" java.lang.NullPointerException
at Q19.main(Q19.java:4)
(4行目のアンボクシングで例外・5行目には到達しない)公式ドキュメント・関連JLS SE11 §5.1.8 Unboxing Conversion↗
AIが作成し、独立した検証を経た解説です(有資格者による監修は経ていません)