Java / 型と変換

暗黙的キャスト(拡大変換)の一覧

結論: 値の範囲が狭い型から広い型への代入は、キャストを書かなくてもコンパイラが自動で変換します(拡大プリミティブ変換)。順番は byte → short → int → long → float → double で、char は int 以上へ自動で変換されます。ただし int → float、long → float、long → double は「拡大」でも精度(下位の桁)が落ちることがあります。

自動で変換される組み合わせ

変換元 自動で代入できる変換先
byte short int long float double
short int long float double
char int long float double
int long float double
long float double
float double

注意点:

  • char と byte・short の間は、どちら向きも自動変換されません(char は符号なし 0〜65535、short は符号あり −32768〜32767 で、互いに範囲を包含しないため)。
  • boolean は他のどの数値型とも変換できません。

コード例

int i = 100;
long l = i;          // OK: int → long
double d = l;        // OK: long → double
char c = 'A';
int code = c;        // OK: char → int(65)

int big = 16_777_217;          // 2の24乗 + 1
float f = big;                 // OK だが精度が落ちる
System.out.println((int) f);   // 16777216

byte a = 1, b = 2;
// byte sum = a + b;           // コンパイルエラー: a + b の型は int
int sum = a + b;               // OK

最後の例のとおり、byte・short・char 同士の算術演算は、計算の前に int へ拡大されます(数値昇格)。そのため結果は int になり、byte へ戻すにはキャストが必要です。

原理(なぜそうなるか)

拡大変換は、変換先の型が変換元の値の範囲をすべて表せる組み合わせです。値の大きさ(桁数のオーダー)が失われないため、言語仕様(JLS 5.1.2)はキャストなしの代入を認めています。

一方、float の仮数部は 24 ビット、double の仮数部は 53 ビットしかありません。int(32 ビット)を float に、long(64 ビット)を float や double に入れると、表せる範囲には収まっても下位の桁が丸められることがあります。上の 16_777_217 が 16777216 になる例がそれです。範囲は失われないが精度は失われうる、というのがこの3つの組み合わせの性質です。

(この初版はAIが作成。随時書き換え)

索引へ戻る