プリミティブ型とラッパークラスのコードトレース
値の取り出しが起きる場所を、代入・比較・増分・コレクションから探します。nullを安全に比較できる場合と例外になる場合、数値の型を揃える必要がある場合を具体的なコードで解きます。
この単元で学ぶこと
- ボクシングとアンボクシングを説明する
- ==とequalsの条件に応じた結果を求める
- 数値変換とnullによる例外を判定する
本文解説
同じ表示でも型が違う Integer i=7;Long l=7L;は両方printで7になりますが、i.equals(l)はfalseです。i.intValue()==l.longValue()なら数値の昇格後に比較できtrueになります。目的が数値比較かオブジェクト比較かを先に決め、必要な変換を明示します。
欠損値を安全に比べる Integer x=null;Integer y=null;のx==yはtrueで、どちらも同じnull参照を比較します。一方x.equals(y)は受け手がnullなので例外です。java.util.Objects.equals(x,y)ならnullも扱いtrueになります。APIが何を受け取り、どこでメソッドが呼ばれるかを追います。
数値との比較の途中 Integer x=null;System.out.print(x==0);ではxをintへ変換するため例外です。Integer x=null;System.out.print(x==null);では参照として比較するためtrue。記号==だけで判断せず、左右が数値型か参照型かを書き出すと変換を特定できます。
配列の初期値にも差がある new int[1]の要素初期値は0、new Integer[1]の要素初期値はnullです。後者のa[0]+1はアンボクシングで失敗します。ラッパー配列を作っただけでは、各要素に数値0のIntegerが自動で作られるわけではありません。
増分と連結の順序 Integer a=2;Integer b=a;System.out.print(a+++":"+a+":"+b);は2:3:2です。a++は古い値を式の結果に使ってaを更新し、bは元の値を参照したままです。読みやすさのため実務では一行に副作用を詰め込まず、更新と表示を分けることも検討します。
文字の解析条件 Integer.parseInt(" 8 ")は自動で前後空白を無視しません。明示的にtrim()してから解析すれば8です。Integer.parseInt("ff",16)は255になります。数字の文字列が持つ表記の基数と、得られる整数値を区別します。
ラッパー間の変換を飛ばさない Long x=1;はintからLongへ直接ボックス化できずコンパイルエラーです。Long x=1L;やLong.valueOf(1)なら可能です。一方long x=Integer.valueOf(1);はIntegerからintへ取り出した後、longへ拡大できます。許される変換の並びが異なります。
コレクションでも型が働く ArrayList<Integer>へ数値を追加する際はボクシング、getした値をintへ代入する際はアンボクシングが入ります。nullも要素にできるのでgetの結果を加算すると例外になることがあります。またlist.remove(1)はint添字、remove(Integer.valueOf(1))は値に一致する要素の削除となり、オーバーロードの違いにも型が影響します。
図解
重要ポイント
- intとIntegerは同じ型ではない。
- nullのラッパーをアンボクシングすると例外になる。
- Integer.equalsは相手の型とint値を比較する。
- ラッパーは不変で、++は共有オブジェクトの値を変更しない。
間違えやすい点
- Integer同士の==を一般的な数値比較として使わない。
- parseIntはint、valueOfはIntegerを返す。
- 大きい値のキャッシュ範囲を実装共通と決めつけない。
用語解説
- ボクシング
- int等の値を対応するInteger等の参照型へ変換すること。
- アンボクシング
- ラッパーから対応するプリミティブ値を取り出す変換。
- 値の比較
- 同一参照かどうかとは別に、保持する値を比較すること。
関連教材
参考資料
教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。
- https://www.oracle.com/jp/education/certification/javase-17-programmer-1/
- https://docs.oracle.com/javase/specs/jls/se17/html/jls-14.html#jls-14.4
- https://docs.oracle.com/javase/specs/jls/se17/html/jls-5.html#jls-5.1.8
- https://docs.oracle.com/javase/specs/jls/se17/html/jls-15.html#jls-15.23
- https://docs.oracle.com/javase/specs/jls/se17/html/jls-15.html#jls-15.25
- https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Integer.html
- https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Objects.html
- https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/ArrayList.html
確認問題の出題・採点や学習履歴の保存にはログインが必要です。