类型转换(cast)的原意是“模型铸造”。在适当的时候,Java会将一种数据类型自动转化为另一种。例如,假设我们为某浮点变量赋以一个整数值,编译器会将int自动转换成float。类型转换运算允许我们显式地进行这种类型的转换,或者在不能自动进行转换的时候强制进行类型转换。
想要执行类型转换,需要将希望得到的数据类型置于圆括号内,放在要进行数据转换的值的左边,例如
int i = 200;
long lng = (long) i ;
正如看到的,既可以对数值进行类型转换,亦可以对变量进行类型转换。
在C和C++中,类型转换有时会让人头痛。但是在Java中,类型转换则是一种比较安全的操作。然而,如果要执行一种名为窄化转换的操作,就有可能面临信息丢失的危险。此时,编译器会强制我们进行类型转换,这实际上是说:“这可能是一件危险的事情,如果无论如何要这么做,必须显式地进行类型转换”。而对于扩展转换,则不必显式地进行类型转换,因为新类型肯定能容纳原来类型的信息,不会造成任何信息的丢失。
Java允许我们把任何基本数据类型转换成别的基本数据类型,但布尔型除外,后者根本不允许进行任何类型的转换处理。“类”数据类型不允许进行类型转换。为了将一种类转换成另一种类,必须采用特殊的方法。
截尾和舍入
在执行窄化转换时,必须注意截尾与舍入问题。例如,如果将一个浮点值转换为整数值,Java会如何处理呢?在下面的示例中可以找到答案,
(int)0.7 结果:0
(int)0.4 结果:0
(int)0.7f 结果:0
(int)0.4f 结果:0
因此,在将float或double转换为整型值时,总是对该数字执行截尾。如果想要得到舍入的结果,就需要使用java.lang.Math中的round()方法,例如
Math.round(0.7)结果:1
Math.round(0.4)结果:0
Math.round(0.7f)结果:1
Math.round(0.7f)结果:0
提升
如果对基本数据类型执行算术运算或按位运算,大家会发现,只要类型比int小(即char、byte、short),那么在运算之前,这些值会自动转换为int。这样一来,最终生成的结果就是int类型。如果想把结果赋值给较小的类型,就必须使用类型转换(既然把结果赋值给较小的类型,就可能出现信息丢失)。通常,表达式中出现的最大的数据类型决定了表达式最终结果的数据类型。如果将一个float值与一个double值相乘,结果就是double;如果将一个int和一个long值相加,结果为long。