キャスト (型変換)
今回は「キャスト」についてみていきます。
「キャスト」とはあるデータ型を他のデータ型に変換することです。前回に代入には「左辺の方が表現範囲が大きくなくてはいけない」という制約があることを記事にしました。例えばint型の変数にdouble型の値を代入することはできません。int型よりdouble型の方が表現範囲が大きいのでエラーになります。このような場合に、double型の値を意図的に「int型に変換」して代入可能なようにするなどで利用できます。
キャストの記述
(変換したい型) 値
変数やリテラルの前に小括弧で変換したい型を囲んで記述します。例えば変数x を int型にキャストしたい場合は「 (int) x 」のように記述します。
サンプルコード
public class sample {
public static void main(String[] args) {
byte a;
int b = 10;
a = b;
}
}
データ表現範囲の大きいものから並べてみます。
double > float > long > int > short > byte
byte型よりint型の方が表現範囲が大きいです。サンプルコードでは byte型の変数a にint型の変数bの値を代入しようとしています。10という値はbyte型でも表現できるのですが、「データ型が左辺の方が表現範囲が大きくなくてはいけない」という制約によりエラーになります。
eclipse では次のようにエラーメッセージがでました。
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
型の不一致: int から byte には変換できません
public class sample {
public static void main(String[] args) {
byte a;
int b = 10;
a = (byte) b;
}
}
5行目で (byte) b とキャストします。変数bはint型からbyte型に変換されました。byte型の変数a にbyte型の変数bを代入するのでエラーになりません。
キャストの問題点
キャストにより変換後の方が表現範囲が小さくなる場合に注意が必要です。変換前のデータを表現できない場合におかしなデータになります。処理上、溢れた部分は切り捨てられます。
public class sample {
public static void main(String[] args) {
byte a;
double b = 12.345;
a = (byte) b;
System.out.println( a ); //結果12
}
}
double型をbyte型に変換しています。doubleは浮動小数点型の1つなので小数点以下も表現できます。byteは整数型の1つなので整数しか表現できません。浮動小数点型から整数型に変換した場合は小数点以下は切り捨てられ整数になります。
public class sample {
public static void main(String[] args) {
byte a;
short b = 128;
a = (byte) b;
System.out.println( a ); //結果 -128
}
}
byte型の表現範囲は「-128~127」です。表現範囲を超えた「128」の値の変数をキャストすると「-128」と負数になりました。

128は2進数では「10000000」になります。byte型は8bitなので最上位である8bit目は符号用ビットです。キャストでshort型からbyte型に変換したことにより最上位が「1」になってしまい符号が変わります。Javaは負数を「2の補数」で処理しているので2進数の「10000000」は-128になります。
public class sample {
public static void main(String[] args) {
byte a;
short b = 256;
a = (byte) b;
System.out.println( a ); //結果 0
}
}
上記サンプル「128」は2進数でも8bitの範囲で処理できます。次は9bit目に「1」がある256をキャストするとどうなるかみてみます。

結果は「0」になります。キャスト後に溢れた部分は切り捨てられ無視されているのがわかります。
このようにキャストする場合は、符号ビットに影響しないか、溢れた部分が切り捨てられて予想外の値にならないか十分注意が必要になります。

