1.类型转换指令
- 作用:用于将两种不同的数据类型进行相互转换。其实也就是用于基本数据类型(出去
bool
类型)之间的相互转换。 - 类型转换指令分为宽化类型转换和窄化类型转换。
1.1 宽化类型转换(自动类型转换)
- 从小范围类型转换到大范围类型的安全转换称为宽化类型转换。例如从
int
转换成long
。 - 指令包括:如图中所示,图中每一条红色的线,就对应着一条指令。例如从
int
到long
,就对应着i2l
这条指令,其余类推。 - 宽化类型转换存在精度损失,例如从
int
到float
,或者从long
到double
,可能会丢失掉几个最低有效位的值。即使存在损失,JVM
也不会抛出异常。
例子:下图中的代码对应的宽化类型转换指令,如下图所示。
byte
、short
、char
被当做是int
进行处理,例如byte
到long
,使用的是i2l
指令(而没有b2l
这样一个指令)。这样一来,可以节省指令资源,因为指令总数不能超过256个;同时,局部变量表中的槽位固定为32
位(4
个字节),byte
、char
、short
在存入局部变量表中的时候,都会占用一个槽位(32
位),也就是一个int
数据类型所占的位数,从这个角度说,直接把它们当成int
进行处理,没必要特意区分这三种数据类型。
例子:如下图所示,byte
到long
,使用的是i2l
,byte
到double
,使用的是i2d
。而byte
到int
,没有指令。
1.2 窄化类型转换(强制类型转换)
- 从大范围的数据类型到小范围的数据类型的转换称为窄化类型转换。
- 对应的指令包括:如图中黄色部分所示。需要注意的是,存在
int
到byte
、short
、char
的转换指令,但是不存在long
、double
、float
直接到byte
、short
、char
的指令。 - 窄化类型转换也存在精度损失的问题。即使存在损失,
JVM
也不会抛出异常。
例子:
可以看到,long
、double
、float
直接到byte
、short
、char
的指令,是通过两条指令达到的,先转到int
,然后再从int
转成byte
、short
、char
。例如float
到byte
,使用的是f2i
,i2b
这两条指令。
- 对于
NaN
、无穷大的窄化类型转换:
例子:
一个浮点数转换为整数:
1)如果浮点数是NaN
,转换为整数0
2)如果浮点数是正无穷大/
负无穷大,转换为整数,则转换为整数的能够表示的最大值/
最小值。
一个double
转换为float
类型:
1)如果double
是NaN
,转换为float
也是NaN
2)如果double
是正负无穷大,转换为float
也是正负无穷大
3)如果double
太小,无法用float
表示,则转换为正负0
更多JVM文章请访问我的JVM专栏:
https://blog.csdn.net/u011069294/category_10113093.html