サイズが大きい型から小さい型への変換
int型からshort型への変換や、long型からint型への変換などサイズが大きい型から小さい型への変換の場合、キャスト演算子を使って明示的に型が変更されることを示す必要があります。
まず間違った記述です。次の例を見てください。
int i = 10; short s = i;
int型の値をshort型の値に単に代入しています。このプログラムをコンパイルすると「精度が落ちている可能性」というコンパイルエラーが表示されます。このようにサイズが大きい型から小さい型へ変換を行う場合はキャスト演算子が必須となります。
よって次のように記述する必要があります。
int i = 10; short s = (short)i;
キャスト演算子を使うことによってエラーは発生せずに型の変換が行われます。
数値リテラルを指定した場合の特例
単に整数を記述した場合はint型の値として扱われます。よって次のように記述した場合はint型の値をキャストせずにshort型の変数に代入しようとすることになります。
short s = 10;
これはサイズが大きい型から小さい型への変換となるのでエラーとなるはずですが、数値そのものをshort型またはbyte型に代入した場合はキャストを行わなくてもエラーとなりません。この場合は自動的に型が変換されます。
ただし自動的に型が変換されるのはshort型またはbyte型の範囲内にある整数を代入しようとした場合だけです。次の例のようにshort型の範囲を超えた整数を直接代入しようとすると「精度が落ちている可能性」というコンパイルエラーが発生します。
short s = 345321;
変換によって数値の情報が失われる場合
大きなサイズの型から小さい型への変換の場合、変換の対象となる数値が変換後のデータ型が扱える範囲を超えてしまうと正しい数値として変換が行えなくなります。
次の例を見てください。
int i = 10; short s = (short)i;
この場合、int型の変数に格納された数値の10は、変換後のshort型でも扱うことができます。その為、変換後の値も10のままです。
では次の例を見てください。
int i = 345321; short s = (short)i;
この場合、int型の変数に格納された数値の345321は、変換後のshort型で扱える範囲を超えてしまいます。その為、short型の変数にはどんな数値が格納されるのかは分かりません。
また浮動小数点数から整数へ変換する場合には、整数では小数点以下の値は扱えませんので変換後は切り捨てられます。次の例を見てください。
double d = 12.345; int i = (int)d;
この場合、float型の数値をint型の数値に変換していますが、int型は整数した扱えない為に変換前の値12.345のうち小数点以下が切り捨てられて12がint型の変数に格納されます。
byte型、short型、char型の注意点
「型変換の基本ルール」の一覧表を見て頂くと分かりますがshort型からchar型への変換、逆にchar型からshort型への変換がどちらも大きいサイズから小さいサイズへの変換となっています。short型とchar型はどちらも16ビットのデータ型なのですが、取り扱うことができる値の範囲が異なります。
char 0~65535 short -32768~32767
例えばchar型の40000という数値をshort型に変換すると情報が失われてしまいます。またshort型の-300という数値をchar型に変換すると情報が失われてしまいます。
またbyte型からchar型に変換する場合、byte型は8ビットでありchar型は16ビットなのですがbyte型は負の値を扱えるのに対してchar型は正の値しか扱う事ができません。
char 0~65535 byte -128~128
例えばbyte型の-17という数値をchar型に変換すると情報が失われてしまいます。
サンプル
では簡単な例で試しておきます。
class JSample4_1{ public static void main(String args[]){ int i = 345321; short s = (short)i; System.out.println("i = " + i); System.out.println("s = " + s); i = 1829; s = (short)i; System.out.println("i = " + i); System.out.println("s = " + s); double d = 12.345; i = (int)d; System.out.println("d = " + d); System.out.println("i = " + i); } }
コンパイル後に実行すると次のように表示されます。
( Written by Tatsuo Ikura )