ラッパークラス(Integer キャッシュと == の参照比較)難易度 高無料
次のコードの出力として正しいものを選べ。
1 public class Q18 {
2 public static void main(String[] args) {
3 Integer a = 100, b = 100;
4 Integer c = 200, d = 200;
5 System.out.println((a == b) + " " + (c == d));
6 }
7 }
- A
true false - B
true true(Integerの==は常に値を比較する) - C
false false(オートボクシングされたIntegerは常に新しいオブジェクトになる) - Dコンパイルエラー(
Integer型どうしを==で比較することはできない)
正解・解説・誤答理由・ひっかけを見る▼ open
✓ 正解:AAI作成・独立検証済
解説
Integer a = 100; のような記述はオートボクシングにより内部的に Integer.valueOf(100) が呼ばれる。
Integer.valueOf(int) は-128 〜 127 の範囲の値については、あらかじめ用意されたキャッシュ済みインスタンスを使い回す(同じ値なら同一オブジェクトを返す)。
a・b は 100(キャッシュ範囲内)なので、同一のキャッシュ済みオブジェクトを参照する。参照を比較する == は true。
c・d は 200(キャッシュ範囲外)なので、valueOf は都度新しい Integer オブジェクトを生成する。
値は等しくても参照が異なるため、c == d は false。
出力は "true false"。
- B
==はラッパー型では参照比較。200はキャッシュ範囲外のためc・dは別オブジェクトになりfalse。 - C-128〜127の範囲は
Integerのキャッシュが効き、同じ値なら同一オブジェクトが再利用される。a == b(値100)はキャッシュ範囲内なのでtrue。 - D
Integerは参照型であり==による比較自体は文法上合法(意味的には参照比較になるというだけ)。コンパイルエラーにはならない。
ひっかけ: 「
Integer 同士を == で比較すれば値が等しい限り常に true」という思い込みが典型的な罠。== は参照比較であり、たまたま-128〜127というキャッシュ範囲内だから true に見えるだけ。値そのものを安全に比較するには常に equals() を使うべき。コマンド例と想定される挙動(未実行)
出力: true false
公式ドキュメント・関連Integer.valueOf(int)(SE11 API・キャッシュの説明)↗
AIが作成し、独立した検証を経た解説です(有資格者による監修は経ていません)