Java虚拟机包括许多进行基本类型转换工作的操作码,这些执行转换工作的操作码后面没有操作数,转换的值从栈顶断获得。Java虚拟机从栈顶端弹出一个值,对它进行转换,然后再把转换结果压入栈。
int、long、float、double 类型之间的相互转换,针对这四种类型之间的每一种可能的类型转换,都存在相应的操作码
操作码 |
操作数 |
说明 |
i2l |
(无) |
将int类型的值转换为long类类型 |
i2f |
(无) |
将int类型的值转换为float类类型 |
i2d |
(无) |
将int类型的值转换为double类类型 |
l2i |
(无) |
将long类型的值转换为int类类型 |
l2f |
(无) |
将long类型的值转换为float类类型 |
l2d |
(无) |
将long类型的值转换为double类类型 |
f2i |
(无) |
将float类型的值转换为int类类型 |
f2l |
(无) |
将float类型的值转换为long类类型 |
f2d |
(无) |
将float类型的值转换为double类类型 |
d2i |
(无) |
将double类型的值转换为int类类型 |
d2l |
(无) |
将double类型的值转换为long类类型 |
d2f |
(无) |
将double类型的值转换为float类类型 |
int数据类型向byte、char、short类型的转换(把int类型转化为比int类型占据更小空间的数据类型),这些操作码从操作数栈中弹出一个int类型值,将它转化为能用byte,short或char类型描述的int类型值,然后再把这个转换后的int类型值压入栈。
操作码 |
操作数 |
说明 |
i2b |
(无) |
将int类型值转换为byte类型值 |
i2c |
(无) |
将int类型值转换为char类型值 |
i2s |
(无) |
将int类型值转换为short类型值 |
i2b指令将弹出的int类型值截取为byte类型,然后再对其进行带符号扩展,恢复成int类型压入栈。
i2c指令将弹出的int类型值截取为char类型,然后再对其进行零扩展,恢复成int类型压入栈
i2s将弹出的int类型值截取为short类型,然后再对其进行带符号扩展,恢复成int类型压入栈
java虚拟机中没有把long,float,double类型直接转化为比int类型值占据更小空间的数据类型转换成int类型的操作码。因此,把float转化为byte需要两个步骤:首先,float类型值必须通过f2i指令转化为int类型值,然后,所得的int类型再通过i2b指令转化为byte类型。
尽管有操作码可以把int类型值转换为比int类型值占据更小空间的数据类型(byte,short和char),但并不存在执行相反方向转换的操作码,因为任何byte、char、short类型值在压入栈的时候,就已经有效的转换成int类型了,涉及到byte、char、short类型的运算操作首先都把这些值转化成int类型,然后对int类型值进行运算,最后得到int类型的结果。
例如如下代码:
public class ConvertTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
byte a = 1;
byte b = 1;
byte c = (byte)(a + b);
}
}
用javap工具查看其字节码指令:
Compiled from "ConvertTest.java"
public class ConvertTest extends java.lang.Object{
public ConvertTest();
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_1 //常量1入栈
1: istore_1 //弹出栈顶元素存入位置为1的局部变量
2: iconst_1 //常量1入栈
3: istore_2 //弹出栈顶元素存入位置为2的局部变量
4: iload_1 //取出位置1的局部变量的值入栈
5: iload_2 //取出位置2的局部变量的值入栈
6: iadd //弹出栈顶两个元素做加法,然后结果入栈
7: i2b //转化成byte类型
8: istore_3 //弹出栈顶元素存入位置为3的局部变量
9: return
}
java虚拟机通过截短和带符号扩展的方式,将int转化为byte,long,int, short,byte类型的最高位(“符号位”)指出此int类型值是正还是负。如果符号位为0,值为正;如果符号位为1,值为负。byte类型的第7位为符号位,从int类型值转换到byte类型的时候,第7位的值将会被拷贝到第8位到第31位,这样就产生了一个int类型值,这个值与原来int类型值被转换为byte类型值后所获得的结果具有相同的数值。在执行完截短和带符号扩展后,这个int类型变量中将容纳一个有效的byte类型的值。