暗黙的な変換 (自動型変換)
以下の 2 つの条件を満たす場合、ある型のデータを別の型の変数に代入する際に、自動で型変換が行われます。
- 2 種類のデータは相互に互換性があります
- ターゲット型の値の範囲がソース データの型より大きい (低レベル型のデータは高レベル型のデータに変換されます)
上記2つの条件が満たされた場合に拡大変換(拡大変換)が発生します。例えば、byte型をshort型に変換する場合、short型は値の範囲が大きいため、自動的にshort型に変換されます。
操作中に、異なるデータ型が同じデータ型に変換されるため、整数型、浮動小数点型、および文字型はすべて混合操作に参加できます。自動変換のルールは、低レベル型データから高レベル型データに変換することです。変換ルールは次のとおりです。
- 数値データの変換: byte→short→int→long→float→double。
- 文字型を整数型に変換します: char→int。
上記のデータ型の変換は、左から右の変換シーケンスに従い、最終的に式内の最大範囲の変数を表すデータ型に変換されます。
例1
顧客はスーパーマーケットに買い物に行き、歯磨き粉を 2 箱とティッシュペーパーを 4 箱購入します。このうち、歯磨き粉の価格は 10.9 元、ティッシュペーパーの価格は 5.8 元であり、商品の合計価格を求めます。実装コードは次のとおりです。
public static void main(String[] args) {
float price1 = 10.9f; // 歯磨き粉の価格を定義
double price2 = 5.8; // ティッシュの価格を定義
int num1 = 2; // 歯磨き粉の数量を定義
int num2 = 4; // ティッシュの数量を定義
double res = price1 * num1 + price2 * num2; // 合計金額の計算
System.out.println("レジ係に支払う合計金額は" + res + "円です。"); // 合計金額を出力
}
上記のコードでは、最初に歯磨き粉の価格を保存するために float 型の変数が定義され、次に顔用ティッシュの価格を保存するために double 型の変数が定義され、次に歯磨き粉の数量を保存するために int 型の 2 つの変数が定義されています。その後、結果は出力用に double 型の変数に格納されます。
実行結果を見ると、float、int、double の 3 つのデータ型が演算に参加しており、最終的な出力結果は double 型のデータであることがわかります。この変換は一般に「式内の型の自動昇格」と呼ばれます。
自動型昇格は優れていますが、混乱を招くコンパイル エラーを引き起こす可能性もあります。たとえば、次のプログラムは正しく見えますが、問題が発生します。
byte b = 50;
b = b * 2; // Type mismatch: cannot convert from int to byte
上に示したように、2 行目では「型が一致しません: int から byte に変換できません」エラーが報告されます。
プログラムは、完全に正当なバイト値 50*2 をバイト変数に格納しようとします。ただし、式が評価されると、オペランドは自動的に int 型にプロモートされ、計算の結果も int 型にプロモートされます。このような式の結果は int 型になり、キャストせずに byte 型に割り当てることはできません。実際、この特定のケースでは、割り当てられた値は依然としてターゲットの型に適しています。
したがって、次のように明示的なキャストを使用する必要があります。
byte b = 50;
b = (byte)(b*2);
これにより、正しい値 100 が生成されます。
注: char 型は特殊で、char は int、long、float、double に自動的に変換されますが、byte と short は char に自動的に変換できず、char は byte または short に自動的に変換できません。
明示的な変換 (キャスト)
自動型変換は便利ですが、プログラミングのすべてのニーズを満たせるわけではありません。たとえば、double 型の値を int 型の変数に割り当てる必要がある場合はどうしますか?
double 型の範囲は int 型の範囲より小さいため、この変換は自動的に行われません。この種の変換は、ターゲット データ型に合わせてソース データ型の値を削減する必要があるため、「削減変換」と呼ばれることもあります。
したがって、2 つのデータ型に互換性がない場合、またはターゲット型の値の範囲がソース型の値の範囲より小さい場合、自動変換は不可能となり、強制的な型変換が必要になります。その構文形式は次のとおりです。
(type)変数名
このうち、typeはvariableNameで変換するデータの型、variableNameは変換先の変数名を指します。強制変換の例は以下のとおりです。
int a = 3;
double b = 5.0;
a = (int)b;
int a = 3; // aに3を代入
double b = 5.0; // bに5.0を代入
a = (int)b; // bをint型にキャストして、aに代入
上記のコードでは、double型の変数bの値をint型にキャストしてからaに代入していますが、変数b自体の値は変わりません。
強制型変換では、浮動小数点型の値を整数に変換する場合は小数点以下の桁を直接削除し、整数型を強制的に浮動小数点型に変換する場合はゼロを追加します。小数点以降。
例 2
顧客はスーパーマーケットに買い物に行き、歯磨き粉を 2 箱とティッシュペーパーを 4 箱購入します。このうち、歯磨き粉の価格は 10.9 元、ティッシュペーパーの価格は 5.8 元であり、商品の合計価格を求め、合計価格を計算するときに保存用の int 型データを使用します。実装コードは次のとおりです。
public static void main(String[] args) {
float price1 = 10.9f;
double price2 = 5.8;
int num1 = 2;
int num2 = 4;
int res2 = (int) (price1 * num1 + price2 * num2);
System.out.println("Price:" + res2 + "円");
}
上記例では、double型、float型、int型のデータが演算に参加しており、演算結果はデフォルトでdouble型となり、質問が求める結果はint型の値の範囲が小さいためint型となります。 double 型なので型変換が必要です。