数值类型在内存中直接存储其本身的值,对于不同的数值类型,内存中会分配相应的大小去存储。如:byte类型的变量占用8位,int类型变量占用32位等。相应的,不同的数值类型会有与其存储空间相匹配的取值范围。这时候我们就需要通过“类型转换”来“匹配模型”,,将大的数据类型匹配给小的数据类型,小的数据类型匹配给大的。
在Java中从低级类型到高级类型的转换为自动类型转换,把高级数据类转赋值给低级数据类需要强制类型转换。
自动转换
int类型的数据赋值给byte类型就会报错。
byte类型的数据赋值给int类型没有报错。
这是因为将一个数值范围小的类型赋给一个数值范围大的数值型变量时,jvm在编译过程中俊将此数值的类型进行了自动转换。
接下来,还有一个地方需要注意的是:char型其本身是unsigned型,同时具有两个字节,其数值范围是0 ~ 2^16-1,因为,这直接导致byte型不能自动类型提升到char,char和short直接也不会发生自动类型提升(因为负数的问题),同时,byte当然可以直接提升到short型。
强制转换
因为在Java,整数类型(byte/short/int/long),对于未声明数据类型的整形,其默认类型为int型。 所以在我们进行byte、short、char任何算术操作时,这些值会在实行操作类型前提升为int类型,并且结果值的类型也是int。
s1+s2的值赋值给s3我们就要进行强制类型抓换或者把s3的数据类型改为int。
对于 int 类型的运算则不用转换,因为默认就是 int 型;对于 char,byte 或者 short,混合赋值也不需要类型转换。
在浮点类型(float/double)中,对于未声明数据类型的浮点型,默认为double型。
int改为double就不会报错了:
向上转型和向下转型
在进行向上转型时,则不必进行显式的类型转换,因为较大类型的数据肯定能容纳较小类型的数据,会自动进行类型转换,不会造成任何信息的丢失。
在进行向下转型时,可能会发生信息丢失,所以我们要强制转换,明确需要转换的类型。
截断和舍入
当我们在执行“向下转换”时,必须注意数据的截断和舍入问题。若从浮点值转换为整数值时,小数位会被截断。
double d = 3.67;
int i = (int) d;
System.out.println(i);//3
如果我们相对结果进行四舍五入, 可以使用 java.lang.Math 的 round() 方法 。
double d = 3.67;
System.out.println(Math.round(d));//4
round()方法会将原来的数字加上0.5后再向下取整,所以,Math.round(11.5) 的结果为 12,Math.round(-11.5) 的结果为 -11。