#目的
Java言語を含めたプログラミングの学習を始めたばかりの方、既学習者の方は復習用に、
型変換を学ぶ為に書いています。
前回は変数と型について学びました。
今回は型変換についてです。
【Java入門目次】
・変数と型
・型変換 ←今ここ
・変数のスコープ
・文字列の操作
・配列の操作
・演算子
・条件分岐
・繰り返し処理
・クラスについて(準備中)
・抽象クラス(準備中)
・インターフェース(準備中)
・カプセル化(準備中)
・モジュールについて(準備中)
・例外処理について
・ラムダ式について
・Stream APIについて
#型変換
データ型を変換する事です。以下がその方法になります。
・暗黙型変換
・キャストによる型変換
それぞれ見ていきましょう。
##暗黙型変換
小さな型を大きな型に代入する事は可能。
我々プログラマーが明示的に型の変換を行わなくても、コンパイルの時に型を変換してくれる。
左の型から右の型への代入はOK!
byte → short、char → int → long → float → double
class Main {
public static void main(String args[]) {
int number = 10;
// int型のnumberが、float型になる
float numberFloat = number;
System.out.println(numberFloat); // 10.0 ←小数点がついた
}
}
以下は暗黙型変換が出来ませんのでご注意を。
・char型をshort型にするとき
・short型をchar型にするとき
どちらも16ビットのデータ型ではあるが、取り扱う事のできる値の範囲が異なるためです。
以降で記載する、キャストによる型変換を行わなければいけません。
class Main {
public static void main(String args[]) {
// ・ char → short
char a = 100;
// エラーがでる
// short b = a; // Type mismatch: cannot convert from char to short
short b = (short) a; // キャストによる型変換でshort型に変換している
System.out.println(b); // 100
// ・ short → char
short c = 100;
// エラーがでる
// char d = c; // Type mismatch: cannot convert from short to char
char d = (char) c; // キャストによる型変換でchar型に変換している
System.out.println(d); // d
}
}
・大きな型を小さな型に代入する事は不可能。コンパイルエラーになる。
右の型から左の型への代入はNG!
byte → short、char → int → long → float → double
class Main {
public static void main(String args[]) {
int numberInt = 10;
// 大きな型から小さな型への代入はできない。
byte numberByte = numberInt; // Type mismatch: cannot convert from int to byte
System.out.println(numberByte);
}
}
また、以下の型変換によって精度が落ちる危険性があるので注意してください。
class Main {
public static void main(String args[]) {
// 各型の最大値をもった変数を定義
int intMax = Integer.MAX_VALUE;
long longMax = Long.MAX_VALUE;
float floatMax = Float.MAX_VALUE;
// float型の有効桁数は10進数で7桁(2進数で24桁)
// int → float
float floatFromIntMax = intMax;
System.out.println(intMax); // 2147483647
// ↓有効桁数7桁以降の値が失われている(型変換前と異なる結果が出力される)
System.out.println(floatFromIntMax); // 2.14748365E9
// long → float
float floatFromLongMax = longMax;
System.out.println(longMax); // 9223372036854775807
// ↓有効桁数7桁以降の値が失われている(型変換前と異なる結果が出力される)
System.out.println(floatFromLongMax); // 9.223372E18
// double型の有効桁数は10進数でおよそ15桁(2進数で53桁)
// long → double
double doubleFromLongMax = longMax;
System.out.println(longMax); // 9223372036854775807
// ↓有効桁数15桁以降の値が失われている(型変換前と異なる結果が出力される)
System.out.println(doubleFromLongMax); // 9.223372036854776E18
// float → double
double doubleFromFloatMax = floatMax;
System.out.println(floatMax); // 3.4028235E38
// ↓有効桁数15桁以降の値が失われている(型変換前と異なる結果が出力される)
System.out.println(doubleFromFloatMax); // 3.4028234663852886E38
}
}
##キャストによる型変換
大きな型から小さな型への代入はできない。
()キャスト演算子
を使用して、明示的に型変換を行う。
class Main {
public static void main(String args[]) {
double numberDouble = 3.14;
// 大きな型から小さな型への代入はできない。
// int numberInt = numberDobule; // Type mismatch: cannot convert from double to int
// キャスト演算子を用いて、int型に強制的に変換している
int numberInt = (int)number;
System.out.println(numberInt); // 3 と出力される
}
}
変換できないパターンもありますのでご注意を。
文字列をint型にはキャスト演算子を用いて変換できません。
class Main {
public static void main(String args[]) {
// 変換できない例
String str = "おはようございます";
int num = (int)str; // Cannot cast from String to int
System.out.println(str);
}
}
キャスト時の注意
キャストによる型変換によって失われるデータもあるので注意してください。
・大きいサイズから小さいサイズに型変換した時、上位ビットの値が切り捨てられる(データの溢れ)
class Main {
public static void main(String args[]) {
short x = 257; // 16ビット -> 0000 0001 0000 0001
byte y = (byte)x; // 8ビット -> 0000 0001
System.out.println(y); // 1 と出力される
}
}
・少数から整数に変換する際は、小数点以下が切り捨てられる。
class Main {
public static void main(String args[]) {
// また少数から整数に変換する際は、小数点以下が切り捨てられる。
double d = 10.23;
int i = (int)d;
System.out.println(i); // 10 と出力される
float f = 33.44f;
int i2 = (int)f;
System.out.println(i2); // 33 と出力される
}
}
##プロモーション(昇格)
プログラマーの意図しない型変換をJavaが自動で行うことがあります。
以下で説明します。
###オペランド(演算対象)の一方がlong型であり他方のオペランドがfloat型、double型ではない場合、他方のオペランドはlong型に変換されてしまう
class Main {
public static void main(String args[]) {
int a = 1;
long b = 2;
// 演算前に変数aがlong型に変換されてしまう
int c = a + b; // Type mismatch: cannot convert from long to int
}
}
↓ 解決策
class Main {
public static void main(String args[]) {
int a = 1;
long b = 2;
int c = (int)(a + b); // 演算結果をint型にキャストする事でエラーは消えます
System.out.println(c); // 3
}
}
###オペランド(演算対象)の一方がfloat型であり他方のオペランドがdouble型ではない場合、他方のオペランドはfloat型に変換されてしまう
class Main {
public static void main(String args[]) {
int a = 1;
float b = 2.0f;
// 演算前に変数aがfloat型に変換されてしまう
int c = a + b; // Type mismatch: cannot convert from float to int
}
}
↓ 解決策
class Main {
public static void main(String args[]) {
int a = 1;
float b = 2.0f;
int c = (int)(a + b); // 演算結果をint型にキャストする事でエラーは消えます
System.out.println(c); // 3
}
}
###オペランド(演算対象)の一方がdouble型である場合、他方のオペランドはdouble型に変換されてしまう
class Main {
public static void main(String args[]) {
int a = 1;
double b = 2.0;
// 演算前に変数aがdouble型に変換されてしまう
int c = a + b; // Type mismatch: cannot convert from double to int
}
}
↓ 解決策
class Main {
public static void main(String args[]) {
int a = 1;
double b = 2.0;
int c = (int)(a + b); // 演算結果をint型にキャストする事でエラーは消えます
System.out.println(c); // 3
}
}
###オペランド(演算対象)がlong型、float型、double型のいずれでもない場合、双方のオペランドはint型に変換されてしまう
class Main {
public static void main(String args[]) {
byte a = 1;
byte b = 2;
// 演算前に変数a,bがint型に変換されてしまう
byte c = a + b; // Type mismatch: cannot convert from int to byte
}
}
↓ 解決策
class Main {
public static void main(String args[]) {
byte a = 1;
byte b = 2;
byte c = (byte)(a + b); // 演算結果をbyte型にキャストする事でエラーは消えます
System.out.println(c); // 3
}
}
プロモーション(昇格)によって意図しない結果になり、エラーが出てしまう事があると思います。
計算時の数値昇格は意識して気をつけなければいけませんね。
#終わりに
型変換について学びました。
次回は変数のスコープを掘り下げていこうと思います。