Javaの「自動型変換」を初心者向けにやさしく解説
ちょっと混乱しやすいテーマだけど、ここを押さえると「なんでエラー?」がグッと減る。例題で体感しながらいこう。
自動型変換の基本ルール
- 大きい器に合わせる: 計算で型が混ざると、Javaは安全なほう(大きい器)にそろえる。
順番は「int → long → float → double」の方向に広がる。 - 整数だけの計算はintに昇格:
byteやshort、charを足したり引いたりすると、まずintになる。 - 逆方向(大きい器 → 小さい器)は自動ではやらない: 明示的なキャストが必要。誤差やオーバーフローの危険があるから。
よくある型とふるまい
- byte/short/char: 計算すると結果は
intに昇格 - int: 基本の整数型。整数の四則演算の土台
- long:
intより大きい整数。混ざるとlongに合わせる - float/double: 小数。混ざると最も大きいほう(たいてい
double)に合わせる
例題で理解する
異なる型の混在(int × double)
int a = 16;
double b = 2.0;
double result = a / b; // aはdoubleに自動変換される
System.out.println(result); // 8.0
Java- ポイント:
intとdoubleを計算すると、doubleにそろう。
整数同士でも「型昇格」する(short + short)
short s1 = 14;
short s2 = 8;
// short s3 = s1 + s2; // コンパイルエラー:結果はint
short s3 = (short)(s1 + s2); // キャストするとOK
System.out.println(s3); // 22
Java- ポイント:
short + shortの結果はintになる。shortに戻したいならキャスト。
単項マイナス(-)でも型昇格が起きる
short s = 12;
// short t = -s; // コンパイルエラー:-sの結果はint
short t = (short)(-s); // キャストが必要
System.out.println(t); // -12
Java- ポイント: 演算子がつくと
intになることがある。代入先に注意。
整数の割り算は小数が切り捨てられる
int x = 5;
int y = 2;
int z = x / y;
System.out.println(z); // 2(2.5じゃない)
Java- 小数が欲しいなら型をdoubleにそろえる
double z2 = (double)x / y; // 片方をdoubleにするとOK
System.out.println(z2); // 2.5
Javalongとの混在
int i = 1_000_000_000;
long l = 2L;
long r = i * l; // 結果はlong
System.out.println(r); // 2000000000
Java- ポイント:
longが混ざると結果はlong。オーバーフロー対策にも有効。
floatとdoubleの違い
float f = 0.1f; // floatは末尾にfが必要
double d = 0.1; // doubleがデフォルト
double r = f + d; // 結果はdouble
System.out.println(r);
Java- ポイント: 浮動小数は誤差が出ることがある。混ぜると
doubleに統一。
明示的キャストの失敗例(注意)
double val = 10 * 0.2; // 2.0
int n = (int)val; // 2(小数切り捨て)
System.out.println(n); // 2
Java- ポイント: キャストは「丸め」ではなく「切り捨て」。必要なときだけ使う。
よくある落とし穴と回避法
- short/byteの計算結果はint:
- 回避: 代入先も
intにするか、必要なときだけキャストする。
- 回避: 代入先も
- 整数割り算で小数が消える:
- 回避: 少なくとも片方を
doubleにする((double)a / b)。
- 回避: 少なくとも片方を
- 小さい型へのキャストは危険:
- 回避: 値の範囲が収まるか確認。桁あふれや誤差を受け入れる場合のみ。
- floatとdoubleの混在:
- 回避: 可能なら
doubleに統一。floatを使うなら末尾fを忘れない。
- 回避: 可能なら
手を動かして慣れるミニ練習
練習1: 出力を予想してみる
byte b1 = 50;
byte b2 = 70;
// byte b3 = b1 + b2; // 何が起きる?どう直す?
int sum = b1 + b2; // 代替案
System.out.println(sum);
Java- 問: ここでコメントを外すと何が起きる?なぜ?どう直せる?
練習2: 小数を得るには
int a = 7;
int b = 2;
double c = a / b; // 期待どおり?
double d = (double)a / b; // 何が変わる?
System.out.println(c);
System.out.println(d);
Java- 問:
cとdの違いを説明して。
練習3: キャストの影響を確認
double price = 199.99;
int rounded = (int)price; // 切り捨て
System.out.println(rounded);
Java- 問: これを四捨五入にしたいならどう書く?
ヒント:
Math.round(price)はlongを返す。(int)Math.round(price)で整数へ。
実務でのおすすめ方針
- 計算の目的に合わせて型を選ぶ: 小数が絡むなら最初から
doubleに統一。 - 中間結果の型に気づく癖をつける: 代入先より「計算の結果の型」を意識。
- キャストは最後の手段: 範囲や誤差の影響を理解したうえで使う。
- 定数は型を明示:
2.0(double)、2L(long)、0.1f(float)。
