型変換(キャスト)の全体像
キャストは「コンパイラが自動で変換しない型へ、開発者の意図で変換を命じる」操作です。プリミティブ間の縮小変換(double → int など)や、参照型の上下変換(親子関係の型)で使います。キャストは「値が失われる」「失敗すると例外」が起こりうるため、どんな変換か、何が起きるか、どこで安全確認するかを理解するのが重要です。
プリミティブのキャスト(縮小変換の基本)
小数から整数へのキャストは「切り捨て」
double d = 3.9;
int n = (int) d; // 3(小数点以下は切り捨て)
long m = (long) -3.9; // -3(負でも0方向へ切り捨て)
Javaキャストは丸めではなく「0方向への切り捨て」です。表示目的の丸めなら Math.round, Math.floor, Math.ceil を使い分けます。
範囲外へのキャストはオーバーフローする
int x = 130;
byte b = (byte) x; // -126(byteの範囲 -128..127 にラップしてしまう)
Java縮小変換では「値を保てない」ことがあります。境界を超える可能性があるなら、事前に範囲チェックしてからキャストします。
int v = 200;
if (v < Byte.MIN_VALUE || v > Byte.MAX_VALUE) throw new IllegalArgumentException();
byte ok = (byte) v;
Java演算で昇格した結果へのキャスト
byte a = 10, b = 20;
// a + b は int に昇格
byte s = (byte) (a + b); // 代入時だけ必要なキャストをまとめて書く
Java(式) 全体を括弧でまとめてからキャストするのが安全です。部分的なキャストは意図せぬ結果を招くことがあります。
参照型(オブジェクト)のキャスト(上向き・下向き)
アップキャスト(上位型へ)は安全で暗黙可
class Animal {}
class Cat extends Animal {}
Cat c = new Cat();
Animal a = c; // アップキャスト(暗黙、自動)
Java子から親へは常に安全です。API受け渡しで「広い型」を使いたいときに自然に行われます。
ダウンキャスト(下位型へ)は明示必須で要確認
Animal a = new Cat();
Cat c = (Cat) a; // ダウンキャスト(明示)
Java参照の実体が Cat でないと ClassCastException になります。安全に行うには「型チェック」を合わせます。
Animal a = getAnimal();
if (a instanceof Cat) {
Cat c = (Cat) a; // 安全
}
JavaJava 16+ ならパターンマッチで簡潔に書けます。
if (a instanceof Cat c) {
// c を Cat として使える
}
Javaキャストは「実体に依存」する
Animal a = new Animal();
Cat c = (Cat) a; // 実体がCatでないため ClassCastException
Java変数の型ではなく「中身の実体」が重要です。設計として「下位型を前提にしない」インターフェース化やメソッド提供を考えましょう。
キャストと丸め・文字コード(数値の意味を守る)
丸めたいなら Math を使う
double d = 3.5;
int r = (int) d; // 3(切り捨て)
int round = (int) Math.round(d); // 4(四捨五入)
int floor = (int) Math.floor(d); // 3(下方向)
int ceil = (int) Math.ceil(d); // 4(上方向)
Java「値の意味」を守るには丸めルールを明示します。表示だけなら printf("%.2f") が最短です。金額の厳密丸めは BigDecimal を選択します。
char とコードポイント
char c = 'A';
int code = (int) c; // 65
char j = (char) 0x3042; // 'あ'
Javachar は UTF-16 のコード単位です。BMP外(U+10000以上)は2単位(サロゲートペア)になるため、文字数操作では codePoints() を使うほうが安全です。
文字列と数値の変換は「キャストではない」
パースと文字列化を使う
String s = "123";
// int x = (int) s; // NG:キャストではできない
int x = Integer.parseInt(s); // OK:パース
String t = String.valueOf(456); // OK:文字列化
Java「参照型同士のキャスト」で値の変換はできません。文字列⇔数値は「APIで変換」です。
ラッパー型とキャストの違い(オートボクシングに注意)
ラッパー間のキャストはできない
Number n = Integer.valueOf(10);
// Long l = (Long) n; // NG:実体がIntegerなので失敗
Java「数値の型を取り替える」には、いったんプリミティブへ取り出してから作り直します。
Number n = Integer.valueOf(10);
long l = n.longValue(); // プリミティブへ
Long L = Long.valueOf(l); // 別ラッパー型を作る
Javanull のアンボクシングは例外になるため防御します。
Integer ix = null;
// int v = ix; // NullPointerException
int v = (ix != null) ? ix : 0;
Javaよくある落とし穴と安全策(重要ポイントの深掘り)
整数除算で先にゼロが確定する
int a = 1, b = 2;
double bad = (double) (a / b); // 0.0(先に0が確定)
double good = (double) a / b; // 0.5(先に浮動小数へ)
Javaキャストの位置で結果が変わります。「計算前に広げる」を意識してください。
キャスト前に範囲・意味を検証する
縮小変換は事前チェックで守ります。
long id = 3_000_000_000L;
if (id > Integer.MAX_VALUE) throw new IllegalArgumentException("範囲外");
int safeId = (int) id;
Java参照型のダウンキャストは「必要最小限」に
設計で下位型を前提にしないよう、共通のインターフェースや抽象メソッドで操作を提供します。どうしても必要なら instanceof で守り、失敗時の代替経路(例外・スキップ)を決めておきます。
例題で身につける
例 1: 入力値を安全に整数化(丸め規則を明示)
public class ParseAndRound {
public static void main(String[] args) {
double tax = 12.345;
int floor = (int) Math.floor(tax); // 12
int ceil = (int) Math.ceil(tax); // 13
int round = (int) Math.round(tax); // 12(.5未満は切り捨て、.5以上は切り上げ)
System.out.println(floor + "," + ceil + "," + round);
}
}
Java例 2: 子型だけが持つメソッドを安全に使う(ダウンキャスト)
class Animal { void speak() { System.out.println("..."); } }
class Cat extends Animal { void meow() { System.out.println("meow"); } }
public class CastDemo {
static void callIfCat(Animal a) {
if (a instanceof Cat c) { // パターンマッチ(Java 16+)
c.meow(); // 安全に子型メソッドへアクセス
} else {
a.speak();
}
}
public static void main(String[] args) {
callIfCat(new Cat()); // meow
callIfCat(new Animal()); // ...
}
}
Java例 3: オーバーフローを避けるために「先に広げる」
public class OverflowSafe {
public static void main(String[] args) {
int big = 1_000_000;
long safe = (long) big * big; // 片方を先に long へ
System.out.println(safe); // 1000000000000
}
}
Java仕上げのアドバイス(重要部分のまとめ)
キャストは「意図」と「失うもの」を明確にして使います。プリミティブ縮小は切り捨てとオーバーフローに注意し、必要なら丸め関数や範囲チェックを併用する。参照型のダウンキャストは instanceof で安全確認し、設計としては下位型依存を減らす。文字列⇔数値はキャストではなく API で変換、ラッパー間の変換も一度プリミティブへ。演算前に広い型へ変換する位置を意識すれば、整数除算やオーバーフローの罠を確実に避けられます。
