初心者のJavaプログラミング

プログラミングガチ初心者がIT業界を目指して頑張ります。

【第4回】初心者のJavaプログラミング【型変換】

Javaでは異なる型のデータを一つの式で使えます。
ですが、フリーダムに何でもオッケーではなく型を変換する規則があるので今日はそれの説明です。

式の評価中の変換規則

1.整数拡張

整数拡張というものがあります。これは式の中で、char型、byte型、short型を使用している場合、式の評価中だけint型になります。
式というのはオペランドとオペコードがあるやつです。


例えば、5 + 3 という場合、5が左オペランド(計算対象)、3が右オペランドと言います。そして、+ をオペコード(演算子)と言います。

ここである疑問が浮かぶと思います。short型(16ビット)で宣言したのにint型になるんだったら、結局最初からint型で宣言しておけばいいじゃん、と。私も最初そう思いました。しかし、整数拡張が行われるのは式の評価中だけなんです。なので、short型で宣言した変数が物理的に大きくなるということではないので注意が必要です。

実際のコードで見てみるとこんな感じです。

int n1 = 5;
short n2 = 3;
int kekka = n1 + n2;
// n1(int型) + n2(short型) ですが、式の評価中だけn2がint型に整数拡張されます。

2.型拡張

整数拡張が行われた後に型拡張というものが行われます。これはコンパイラが左右のオペランドを比較して、大きい方のオペランドの型に変換することです。
大きい順に、double float long int です。
実数の中でも一番大きい型のdouble、その次のfloat、次に整数の型で一番大きいlong、そしてintというように続きます。
以下型変換のアルゴリズムです。
(1)左右どちらかのオペランドがdouble型 yes→ もう一方をdouble型に
↓ no
(2)左右どちらかのオペランドがfloat型 yes→ もう一方をfloat型に
↓ no
(3)左右どちらかのオペランドがlong型 yes→ もう一方をlong型に
↓ no
(4)左右どっちもint型に

int n1;
float n2;
float kekka = n1 + n2;
// 左右のオペランドを見てn2がfloat型なので、式はn1(int型)が型拡張されてfloat型に変換されます

代入時の型変換

代入文で左辺と右辺の型が異なるときにどうなるかというと、右辺の型が左辺の型に変換されます。なので、左辺の型の方が大きい場合は特に問題はないです。左の方が大きい箱なのでおっけーなんです。
ですが、右辺の型の方が大きいと問題が発生する場合があります。

f:id:fightingneetkun:20140713141228j:plain
なんとなくイメージつかめればと思い描きました!
左が大きい箱の場合には右の小さい箱は入りますが、
右が大きい箱の場合は左の箱に入りきりません。

以下例です。どのような結果になるでしょうか。

int n1;
short n2 = 5;
n1 = n2;
System.out.println(n1);

これは左の型の方が大きいので問題なく実行できると思います。

次の例はどうなるんだべか。

int n1 = 5;
short n2;
n2 = n1;
System.out.println(n2);

コンパイルできません!
なぜなら右辺の型の方が大きいからです。
そこで必要なのが縮小変換という作業です。
いきます!

int n1 = 5;
short n2;
n2 = (short)n1; // 縮小変換
System.out.println(n2);

(short)n1 と書くことにより、元々int型だったn1がshort型に縮小変換されます。
これでコンパイルは通ると思います。

実数の型と整数の型

実数の型を整数の型に代入すると小数点以下の切り捨てが行われます。

float f = 123.4567f;
int i = (int)f;
System.out.println(i);

少数部分が破棄されます。intは整数しか表せないからです。
結果は123と出るはずです。

最後に問題

どんな結果になるでしょう。

class Katahenkan {
	public static void main( String args[] ) {
		short a = 10;
		short b = 20;
		short c = a + b;
		System.out.println(c);
	}
}

結果コンパイルできません。
short型のをshort型に入れて何の問題があるんだべと初見で思いましたw
落ち着いて考えると、右辺はshort型じゃないんですよね。
fmfm、じゃあこうなおそう!

class Katahenkan {
	public static void main( String args[] ) {
		short a = 10;
		short b = 20;
		short c = (short)a + (short)b;
		System.out.println(c);
	}
}

結果コンパイルできません。
なんでかなーと思ったら、式の評価中の型変換のアルゴリズムを見たら分かると思います。