型変換は「データを正しい器に入れ直す」作業
業務システムでは、同じ「値」でも、場面によって求められる型が変わります。
画面からは文字列で届く、計算には数値が必要、DB には文字列で保存する──この「型の行き来」をきちんと設計するのが型変換です。
Java では、プリミティブ型(int や double)とラッパークラス(Integer や Double)、String との間を行き来することが非常に多くなります。
ここを雑にやると、NumberFormatException や NullPointerException、桁落ち・丸め誤差など、業務バグの温床になります。
まずは「文字列 ↔ 数値」の基本型変換を押さえる
String → int / long の変換
文字列から整数への変換は、業務で一番よく出てきます。代表的なのは Integer.parseInt と Integer.valueOf です。
String s = "123";
// プリミティブ int に変換
int i = Integer.parseInt(s);
// ラッパー型 Integer に変換
Integer iObj = Integer.valueOf(s);
JavaparseInt はプリミティブ int を返し、valueOf は Integer オブジェクトを返します。
オブジェクトが欲しい場面(コレクションに入れる、null を扱いたいなど)では valueOf、
単純な計算でパフォーマンス重視なら parseInt、という使い分けが基本です。
ここで重要なのは、「数値として正しい文字列でないと NumberFormatException が出る」ことです。
Integer.parseInt("123"); // OK
Integer.parseInt("123a"); // NumberFormatException
Integer.parseInt(""); // NumberFormatException
Integer.parseInt(null); // NullPointerException
Javaこの「失敗し得る」という感覚を持っておくのが、型変換を安全に扱う第一歩です。
int / long → String の変換
逆に、数値を文字列にしたい場面も多いです。代表的な方法は String.valueOf と toString です。
int i = 123;
// String に変換
String s1 = String.valueOf(i);
String s2 = Integer.toString(i);
JavaString.valueOf は null にも優しく、ラッパー型にもそのまま使えるので、実務ではかなり出番が多いです。
Integer iObj = null;
String s = String.valueOf(iObj); // "null" という文字列になる
Java「null をどう扱うか」は要件次第なので、null のときは空文字にしたい、などのポリシーがあるなら、ユーティリティでラップしてしまうのがよくあるパターンです。
プリミティブ型とラッパークラスの変換と注意点
オートボクシング / アンボクシングのイメージ
Java では、プリミティブ型とラッパークラスの間は自動変換(オートボクシング/アンボクシング)が行われます。
int i = 10;
Integer obj = i; // オートボクシング(int → Integer)
int j = obj; // アンボクシング(Integer → int)
Java一見便利ですが、ここに null が絡むと危険です。
Integer obj = null;
int i = obj; // ここで NullPointerException
Java業務コードでは、「ラッパー型は null になり得る」という前提を常に意識し、
アンボクシングが起きる場所(int に代入、+ 演算など)では特に注意が必要です。
ラッパー型を返すか、プリミティブを返すか
ユーティリティの設計では、「戻り値をプリミティブにするか、ラッパーにするか」がよく議論になります。
- プリミティブを返す:
nullという状態を表現できない代わりに、NPE の心配がない。 - ラッパーを返す: 「値なし」を
nullで表現できるが、アンボクシング時の NPE に注意が必要。
例えば「パースできなかったら null を返したい」ならラッパー型、
「常に何かしらの値(デフォルト値を含む)を返したい」ならプリミティブ型、という設計になります。
実務で使う「安全な型変換ユーティリティ」の例
文字列 → 整数の安全な変換
生の parseInt をあちこちで呼ぶのではなく、「失敗したらどうするか」を含めてユーティリティ化しておくと、業務コードが安定します。
public final class Conversions {
private Conversions() {}
// null / 空白 / 不正な形式 → null、それ以外は Integer
public static Integer toIntegerOrNull(String s) {
if (s == null || s.isBlank()) {
return null;
}
try {
return Integer.valueOf(s.trim());
} catch (NumberFormatException e) {
return null;
}
}
// パースできなければデフォルト値を返す
public static int toIntOrDefault(String s, int defaultValue) {
Integer value = toIntegerOrNull(s);
return value != null ? value : defaultValue;
}
}
Java使う側はこうなります。
String input = getAgeInput(); // 画面からの入力
int age = Conversions.toIntOrDefault(input, 0);
if (age <= 0) {
System.out.println("年齢を正しく入力してください");
}
Javaここで大事なのは、「例外を業務ロジックにばらまかず、ユーティリティで吸収している」ことです。
これにより、画面やバッチのコードは「変換に失敗したら 0 が返る」という前提でシンプルに書けます。
文字列 → 真偽値の変換
真偽値も、画面や設定ファイルから文字列で届くことが多いです。
public static Boolean toBooleanOrNull(String s) {
if (s == null) return null;
return switch (s.trim().toLowerCase()) {
case "true", "1", "yes", "y", "on" -> Boolean.TRUE;
case "false", "0", "no", "n", "off" -> Boolean.FALSE;
default -> null;
};
}
JavaJava 標準の Boolean.parseBoolean は、「"true"(大文字小文字無視)なら true、それ以外は false」という挙動なので、
「不正な値を false とみなしてよいか?」という観点で要件に合わないこともあります。
業務では、「不正な値はエラー扱いにしたい」「null にしたい」といった要件に合わせて、自前の変換ルールを持つことが多いです。
数値型どうしの変換と精度の話
int / long / double 間のキャスト
数値型どうしの変換は、キャストで行います。
int i = 10;
long l = i; // 拡大変換(安全)
long big = 10000000000L;
int small = (int) big; // 縮小変換(桁落ちの可能性)
Javaint → long のような「入れ物が大きくなる」変換は安全ですが、long → int のような「入れ物が小さくなる」変換は、値が範囲外だと桁落ちします。
long big = 3_000_000_000L;
int small = (int) big;
System.out.println(small); // 予想外の負の値になる
Java業務で金額や数量を扱うときは、「どの型まで許容するか」「範囲外をどう扱うか」を決めたうえでキャストする必要があります。
金額・精度が重要な値は BigDecimal で扱う
double や float は二進数の浮動小数点数なので、10 進数の小数を正確に表現できないことがあります。
金額や精度が重要な値には BigDecimal を使うのが定番です。
import java.math.BigDecimal;
BigDecimal price = new BigDecimal("1234.56"); // 文字列からの生成が推奨
BigDecimal taxRate = new BigDecimal("0.1");
BigDecimal tax = price.multiply(taxRate);
Javanew BigDecimal(double) は、double の誤差をそのまま持ち込んでしまうので、
「文字列 → BigDecimal」の変換では new BigDecimal(String) を使うのがベストプラクティスです。
String 以外の型変換と設計の考え方
Enum との相互変換
業務では、「コード値(文字列) ↔ Enum」の変換もよく出てきます。
enum Status {
ACTIVE, INACTIVE;
}
Status st = Status.valueOf("ACTIVE"); // 文字列 → Enum
String name = st.name(); // Enum → 文字列
JavavalueOf は不正な文字列を渡すと IllegalArgumentException になるので、
ここでも「失敗したらどうするか」を含めてユーティリティ化しておくと安全です。
public static Status toStatusOrNull(String s) {
if (s == null) return null;
try {
return Status.valueOf(s.toUpperCase());
} catch (IllegalArgumentException e) {
return null;
}
}
Java「どこで型を決めるか」を意識する
型変換の設計で一番大事なのは、「どこで最初に正しい型に変換するか」です。
- 画面や外部 API からは、まず文字列で受ける。
- できるだけ早い段階で、業務で使う型(
int、BigDecimal、Enumなど)に変換する。 - 以降のレイヤーでは、その型を前提にロジックを書く。
この「早めに正しい器に入れ直す」発想があると、
後ろのレイヤーで「毎回 String からパースする」「毎回 null チェックする」といった重複が減り、バグも減ります。
まとめ:初心者が型変換で身につけるべき感覚
型変換で外したくないポイント
- String ↔ 数値の基本を押さえる
parseInt/valueOf/String.valueOfの役割と違いを理解し、NumberFormatExceptionがいつ出るかを体感しておく。 - プリミティブとラッパーの違いを意識する
nullを扱う必要があるかどうかで、どちらを使うか決める。アンボクシング時の NPE に注意する。 - 「失敗し得る変換」はユーティリティで包む
文字列 → 数値、文字列 → Enum、文字列 → 真偽値などは、try-catch とポリシー(デフォルト値・null・例外)をセットでユーティリティ化する。 - 精度が大事なところでは BigDecimal を使う
金額や割合など、誤差が許されない値はdoubleではなくBigDecimal+ 文字列変換で扱う。
ここまでの感覚が身につけば、「とりあえずキャスト」「とりあえず parseInt」から卒業できます。
