Java | Java 標準ライブラリ:ラッパークラス全体像

Java Java
スポンサーリンク

ラッパークラスとは何かをざっくりつかむ

Java の「ラッパークラス」は、
intdouble のような プリミティブ型(基本型)を “オブジェクトとして包んだクラス” です。

対応はこうなっています。

  • booleanBoolean
  • byteByte
  • shortShort
  • intInteger
  • longLong
  • floatFloat
  • doubleDouble
  • charCharacter

名前の通り「包んでいる(wrap)」のでラッパークラス。
「値そのもの(基本型)」と「オブジェクトとしての箱(ラッパークラス)」がペアになっているイメージです。


そもそも、なぜラッパークラスが必要なのか(目的)

コレクションやジェネリクスは「オブジェクトしか扱えない」

Java のコレクション(List, Map など)やジェネリクスは、基本型を直接扱えません

例えば、これはコンパイルエラーです。

List<int> list;   // ダメ
Java

正しくはラッパークラスを使います。

List<Integer> list;  // OK
list = new ArrayList<>();
list.add(10);        // 実は「10」が Integer に自動変換されている(後述)
Java

List の中には「オブジェクト」しか入れられないので、
基本型の値を オブジェクトに変換して入れるための箱 が必要になる。
それがラッパークラスの一番分かりやすい役割です。

「null を入れたい」場面で必要になる

基本型には null を入れられません。

int x = null;      // コンパイルエラー
Java

ですが、「値がない」という状態を表したいときに、null を使いたくなることがあります。

Integer x = null;  // これは OK(ラッパークラス)
Java

例えば「まだ設定されていない」「DB から値が来ていない」など、
「0 とは違う“未設定”」を表したいときに、ラッパークラスの null が役立ちます。

  • 基本型…常に何かしらの値(int なら 0 など)が入る
  • ラッパークラス…「値あり」か「null(値なし)」の2状態を持てる

この「null を持てるかどうか」の違いも重要です。


オートボクシング / アンボクシング:自動で変換される仕組み(重要)

自分で new しなくても勝手に変換される

昔の Java では、基本型とラッパークラスを自分で変換していました。

int x = 10;
Integer obj = Integer.valueOf(x);  // 包む(ボクシング)
int y = obj.intValue();           // 取り出す(アンボクシング)
Java

今(Java 5 以降)は、コンパイラが自動でやってくれます。
これを オートボクシング / アンボクシング と呼びます。

int x = 10;
Integer obj = x;    // 自動で Integer.valueOf(x) してくれる
int y = obj;        // 自動で obj.intValue() してくれる
Java

見た目は代入しているだけですが、
裏では「オブジェクトへの変換」「中身の取り出し」が行われています。

コレクションに入れるときも自動でラップされる

List<Integer> list = new ArrayList<>();
list.add(10);          // int → Integer に自動変換(オートボクシング)

int v = list.get(0);   // Integer → int に自動変換(アンボクシング)
Java

こういうコードがコンパイルできるのは、
オートボクシング/アンボクシングのおかげです。

ただし「null アンボクシング」は危険(よくあるバグ)

ラッパークラスが null のときに、アンボクシングが走ると NPE(NullPointerException)になります。

Integer obj = null;
int x = obj;     // ここで NullPointerException
Java

内部的には obj.intValue() を呼んでいるのと同じなので、
objnull だと当然落ちます。

ラッパークラスを使うときは、

「この変数、null になり得るか?」
「基本型にアンボクシングするときに大丈夫か?」

を意識しておかないと、気づきにくい NPE を食らいやすくなります。


ラッパークラスが持っている便利メソッドたち

文字列 ←→ 数値の変換(parse 系 / valueOf)

ラッパークラスは、「文字列と数値の変換」をするメソッドを持っています。

int i = Integer.parseInt("123");      // "123" → 123
double d = Double.parseDouble("3.14");
boolean b = Boolean.parseBoolean("true");
Java

逆に、「数値 → 文字列」は基本型でも String.valueOf(...) でできますが、
ラッパークラスの toString() でも同じようなことができます。

Integer n = 123;
String s = n.toString();              // "123"
Java

また、valueOf は「ラッパークラスを返す」バージョンです。

Integer obj = Integer.valueOf("123");  // String → Integer
Integer obj2 = Integer.valueOf(123);   // int → Integer
Java

parseXxx は基本型を返し、valueOf はラッパークラスを返す、
という違いを覚えておくと整理しやすいです。

定数(MAX_VALUE / MIN_VALUE 等)

ラッパークラスは、その型の最大・最小値を表す定数も持っています。

int max = Integer.MAX_VALUE;
int min = Integer.MIN_VALUE;

long lmax = Long.MAX_VALUE;
Java

範囲チェックをするときや、
オーバーフローを意識するときに使われます。


ラッパークラスと equals / == の違い(ここもよくハマる)

== は「参照比較」、equals は「値比較」

ラッパークラスはクラス(オブジェクト)なので、
== は「同じインスタンスかどうか」を比較します。

Integer a = new Integer(100);
Integer b = new Integer(100);

System.out.println(a == b);         // ほぼ確実に false
System.out.println(a.equals(b));    // true(中身の値が同じ)
Java

「値が同じかどうか」を見たいなら、ラッパークラスでも equals を使う必要があります。

小さい整数の「キャッシュ」による罠

実は、Integer など一部のラッパークラスは、
小さい値(-128〜127 の範囲)をキャッシュしています。

Integer x = 100;
Integer y = 100;
System.out.println(x == y);        // true になることが多い

Integer p = 200;
Integer q = 200;
System.out.println(p == q);        // false になることが多い
Java

これがややこしいポイントです。

  • たまたま小さい値だと == が true になることがある
  • でも大きくなると false になる

こんな不安定なものに頼るべきではありません。

ラッパークラス同士の比較は、必ず equals を使う
(またはアンボクシングして基本型同士 == 比較)
と決めておくのが安全です。


「ラッパークラスをいつ使うか」をまとめて整理する

典型的な使いどころ

ラッパークラスを自然に使う場面はだいたい決まっています。

コレクションやジェネリクスの中で数値を扱いたいとき

List<Integer> ages = new ArrayList<>();
Map<String, Long> accessCount = new HashMap<>();
Java

ここはもう「そういうもの」として使うしかありません。

null を使って「値なし」を表したいとき

Integer score = null;  // まだ採点されていない
Java

ここから、

  • 「本当に null で良いのか?」
  • 「Optional<Integer> の方が安全では?」

といった設計の議論につながっていきますが、
ひとまず「基本型には null が入らない」の対策としてラッパークラスがあります。

文字列との変換をするとき

int value = Integer.parseInt(inputText);
Integer obj = Integer.valueOf(value);
Java

値がフォームなどから String として来る場合は、
ラッパークラスの静的メソッドによくお世話になります。


ラッパークラスの注意点と、初心者としての意識ポイント

パフォーマンス面:ボクシングしすぎに注意

ラッパークラスはオブジェクトなので、
基本型よりメモリ・速度の面で重くなります。

特にループで大量にボクシング・アンボクシングを繰り返すと、
無駄なオブジェクト生成が増えてパフォーマンスに影響することがあります。

long sum = 0;
for (int i = 0; i < 1_000_000; i++) {
    Integer x = i;   // 毎回ボクシング
    sum += x;        // 毎回アンボクシング
}
Java

初心者のうちはそこまで気にしなくてもいいですが、

  • 算術計算はなるべく基本型でやる
  • コレクションに入れる必要があるところだけラッパークラス

くらいを意識しておくとバランスが良いです。

null アンボクシングによる NPE に特に注意(重要)

もう一度あえて強調すると、

Integer n = null;
int x = n;  // ここで NPE
Java

このパターンは本当によくやらかされます。

「ラッパークラスから基本型に代入している」ときは、
「このラッパー、null になる可能性は?」と必ず自問してください。

必要なら、

int x = (n != null) ? n : 0;
Java

や、

int x = Optional.ofNullable(n).orElse(0);
Java

のように「null のときどうするか」を明示しておくのが安全です。


まとめ:ラッパークラス全体像を頭の中に描く

ここまでを、初心者向けにぎゅっとまとめるとこうです。

  • ラッパークラスは「基本型をオブジェクトとして包むクラス」
  • コレクションやジェネリクスで数値を扱うときに必須
  • ラッパークラスは null を持てるので「値なし」を表現できる
  • オートボクシング/アンボクシングのおかげで、int と Integer の代入が自然に書ける
  • ただし、null のアンボクシング(Integer → int)で NPE に注意
  • ラッパークラス同士の比較で == を使わず、equals かアンボクシングして基本型比較を使う

タイトルとURLをコピーしました