1. 隐式(自动)类型转换
在 Java(以及其他语言)中,变量具有严格的类型——如果变量声明为 int,它只能存储整数;如果声明为 double,则只能存储浮点数。但在实际程序中,经常需要把一个变量的值“放到”另一种类型的变量中。例如:
- 从方法得到一个 int,但希望把它当作 double 来进行小数计算。
- 把字符的编码以数字形式保存(int),希望得到对应的字符(char)。
- 计算结果是 double,但需要整数结果(int),例如输出整颗苹果的数量。
在 Java 中有两种主要的类型转换方式:隐式(自动)和显式(手动)。
这是什么意思?
隐式转换是指当转换是安全的且不会导致数据丢失时,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 要求你“确认:是的,我理解部分数据可能会丢失!”
语法
type_name variable = (type_name) expression;
示例: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