1. 暗黙的(自動)型変換
Java(他の言語と同様)では変数は厳密な型を持ちます。つまり、変数が int として宣言されていれば整数しか保持できず、double であれば浮動小数点数だけを保持できます。しかし実際のプログラムでは、ある型の変数の値を別の型の変数に「載せ替える」必要がよく生じます。例えば次のような場合です。
- メソッドから int を受け取ったが、小数を含む計算のために double として使いたい。
- 文字のコードを数値(int)として保持しており、実際の文字(char)が欲しい。
- double の計算結果があるが、整数結果(int)が必要(例:丸い個数のリンゴを表示したい)。
Java には主に 2 つの型変換の方法があります。暗黙的(自動)と明示的(手動)です。
これは何か?
暗黙的変換とは、データ損失の恐れがなく安全な場合に、Java が「あなたの介入なしで」自動的に片方の型からもう一方に値を変換してくれることです。
これは、より小さい型の値を、より大きい型の変数に代入するときに起こります。例えば、int → double、char → int、float → double などです。
たとえ話:コップの水(int)とバケツ(double)を想像してください。コップの水をバケツに移せば、こぼれずにすべて入ります。こうした場合、Java は自動変換を許可します。
例: int → double
int apples = 5;
double applesWeight = apples; // int は自動的に double になる
System.out.println(applesWeight); // 5.0
例: char → int
Java では各文字は Unicode の表の数値に過ぎません。したがって、char から int への変換は自動で行われます。
char letter = 'A';
int code = letter; // 'A' は 65(Unicode の文字コード)になる
System.out.println(code); // 65
暗黙的な変換の表
| 元の型 | 暗黙に変換できる先 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
重要: 暗黙的変換は「拡大」方向(小さい型 → 大きい型)でのみ機能します。
2. 明示的(手動)型変換(type casting)
明示的変換は、より大きい型からより小さい型へ、または互換性のない型同士を変換したい場合に必要です。このとき Java は、データが失われる可能性を理解していることを明示するよう要求します。
たとえ話:バケツ(double)の水をコップ(int)に移そうとするようなものです——水の一部はこぼれるかもしれません。Java はあなたに「はい、データの一部が失われ得ることを理解しています」と明示させます。
構文
tip_naznacheniya peremennaya = (tip_naznacheniya) vyrazhenie;
例: double → int
double price = 12.99;
int roundedPrice = (int) price; // 小数部分は単に切り捨てられる
System.out.println(roundedPrice); // 12
注意: 丸めは行われません。小数点以下を「ばっさり」切り捨てるだけです。丸めたい場合は Math.round() を使ってください。
例: int → char
int code = 66;
char letter = (char) code; // 66 は文字 'B'
System.out.println(letter); // B
例: double → float
double d = 3.1415926535;
float f = (float) d; // 精度の一部が失われる
System.out.println(f); // 3.1415927(小数点以下の桁数が少ない)
3. 数値と文字の変換(char と数値)
なぜ可能なのか?
Java の文字(char)は実際には Unicode 表の数値です。そのため、int へ、またはその逆への変換は自由に行えます。
例: char → int
char ch = '\u0416';
int code = ch;
System.out.println(code); // 1046
例: int → char
int code = 8364;
char symbol = (char) code;
System.out.println(symbol); // €
練習: アルファベットを出力
for (int i = 65; i < 65 + 26; i++) {
System.out.print((char) i + " ");
}
// 出力: A B C D ... Z
4. 整数と浮動小数点数の変換
int → double(暗黙)
int count = 10;
double avg = count; // 暗黙の拡大変換
System.out.println(avg); // 10.0
double → int(明示)
double score = 8.75;
int rounded = (int) score;
System.out.println(rounded); // 8
数学的に丸めるには?
小数部分を単に「切り捨てる」のではなく、最も近い整数に丸めたい場合は Math.round() を使います。
double price = 8.75;
int rounded = (int) Math.round(price);
System.out.println(rounded); // 9
5. 縮小変換では何が起こるか?データ損失
例: int → byte
int big = 300;
byte small = (byte) big;
System.out.println(small); // 44 (!)
なぜ 44 なのか?それは byte が保持できる範囲が -128 ~ 127 だからです。値が収まらない場合は、256(剰余)による「切り詰め」が起こります。
例: double → int
double d = 1e20;
int i = (int) d;
System.out.println(i); // -2147483648(int の最小値)
大きすぎる数値は int の範囲に収まらず、「奇妙」な結果になります。
6. 演算時の変換:「混在」型
例: int + double
int a = 3;
double b = 2.5;
double result = a + b; // int は自動的に double になる
System.out.println(result); // 5.5
例: char + int
char ch = 'A'; // 65
int offset = 2;
char next = (char) (ch + offset); // char は自動的に int になる
System.out.println(next); // C
7. 数値と文字列の相互変換
これは厳密には「型変換」ではありませんが、数値を文字列に、またはその逆に変える処理は頻繁に必要になります。
int → String
int x = 123;
String s = Integer.toString(x);
// または単に: String s = "" + x;
String → int
String s = "456";
int x = Integer.parseInt(s);
8. よくあるミスと注意点
ミス1: double → int で小数部分が失われる。 初学者はしばしば、(int) 3.99 の結果が 4 になると思いがちです。実際の結果は 3 で、小数部分は単に切り捨てられます。正しく丸めるには Math.round() を使ってください。
ミス2: 暗黙の「縮小」は動かない。 int x = 300; byte b = x; のようには書けません——コンパイラはエラーにします。明示的に (byte) x と書く必要がありますが、値が byte の範囲外なら結果は予期しないものになります。
ミス3: 互換性のない型間の変換。 (int) "123" のようには書けません。文字列を数値に変換するには Integer.parseInt() を使います。
ミス4: char と int の扱い。 int から char への変換は、Unicode に実在する値に対してのみ意味があります。非常に大きな数値を渡すと、予期しない文字になります。
ミス5: 式の中の混在型。 式に int と double が含まれていれば、結果は常に double です。整数結果を期待していると、プログラムのロジックに思わぬ影響を与えることがあります。
ミス6: 丸めは型変換ではない! (int) x は丸めではなく、単に小数部分を切り捨てるだけです。丸めには Math.round() を使いましょう。
GO TO FULL VERSION