• 第11章 类型转换


    11.1转换操作码
    Java虚拟机包括许多进行基本类型转换工作的操作码,这些执行转换工作的操作码后面没有 操作数,转换的值从桟顶端获得。Java虚拟机从栈顶端弹出一个值,对它进行转換,然后再把转 换结果压入栈。进行int、long, float和double类型之间转换的操作码如表11-1所示,针对这四种 类型之间的每一种可能的类型转换,都存在相应的操作码。

    如表11-2所示的操作码是把int类型转换为比int类型占据更小空间的数据类型。这些操作码 从操作数找中弹出一个int类型值,将它转换为能用byte、short或char类型描述的int类型值,然后 ,把这个转换后的int类型值压人栈。i2b指令将弹出的int类型值截短为byte类型,然后再对其进 行带符号扩展,恢复成int类型。i2s指令将弹出的int类型值截短为short类型,然后再对其进行带 符号扩展,恢复成int类型。i2c指令将弹出的int类型值截短为Char类型,然后再对其进行零扩展 恢复成int类型。

    Java虚拟机中没有把long、float, double类型值直接转换为比int类型占据更小空间的数据类 型的操作码。因此,把float类型值转换为byte类型需要两个步骤:首先,float类型值必须通过f2i 指令转换为int类型值,然后,所得的int类型值再通过i2b指令转换成byte类型值。

    尽管有操作码可以把int类型值转换为比int类型值占据更小空间的数据类型(byte、short和 char),但并不存在执行相反方向转换操作的操作码。因为任何byte、short和char类型值在压入找的时候,就已经有效地被转换成int类型值了。从数组或者堆中的对象中接受byte、short和char 类型值的指令和把这些值压入找的指令都会把它们转换为int类型值。这些指令将在第15章叙述。

    涉及byte、short和char类型的运算操作首先会把这些值转换为int类型,然后对int类型值进行 运算,最后得到int类型的结果。因此,如果把两个byte类型值相加,最后会得到一个int类型的 结果。如果需要得到byte类型结果,必须将这个int类型的结果显式转换为byte类型。例如,下面 的代码会导致编译失败:
    // On the CD-ROM in file opcodes/ex1/BadArithmetic.java
    class BadArithmetic {

    static byte addOneAndOne() {
    byte a = 1;
    byte b = 1;
    byte c = a + b;
    return c;
    }
    }
    该操作能够通过javac的编译,并产生GoodArithmetic.class文件。此文件包含了如下的addOneAndOne()方法的字节码序列:
    0 iconst_1 //push int constant 1.
    1 istore_0 //pop into local variable 0,which is a:
    //byte a=1;
    2 iconst_1 //push int constant 1 again.
    3 istore_1 //pop into local variable 1,which is b:
    //byte b=1;
    4 iload_0 //push a (a is already stored as an int in
    //local
    //variable 0).
    5 iload_1 //push b (b is already stored as an int in
    //local
    //variable 1).
    6 iadd //Perform addition.Top of stack is
    // now (a+b),an int.
    7 i2b //Convert int result to byte (result still
    //occupies 32 bits).
    8 istore_2 // Pop into local variable 3,which is
    // byte c:byte c=(byte)(a+b);
    9 iload_2 // Push the value of c so it can be
    // returned.
    10 ireturn // addition: return c;
    该Convert ()方法演示了Java虚拟机中将int类型值转换为byte类型值的方式。imInt变量开 始的值为125,每经过一次循环,它都会自增1,并转换为byte类型。然后,它的值变为原值与 -1的乘积,最后再次转换为byte类型。这个模拟过程可以快速地显示出在byte类型有效范围的边 界上发生的事情。

    byte类型的最大值为127,最小值为-128.在这个范围内的int类型值被直接转换为byte类型值,而当int类型值超出这个有效范围时,事情就变得有趣起来。

    Java虚拟机通过截短和带符号扩展的方式将int类型值转换成为byte类型值。long、int、 short 和byte类型的最高位(“符号位”)指出此int类型值是正还是为负。如果符号位为0,值为正;如果符号位为1,值为负。byte类型的第7位为符号位。从int类型值转换到byte类型值的时候,第7位的值将会被拷贝到第8位到第31位。这样就产生了一个int类型值,这个值与原来int类型值被转换为byte类型值后所获得的结果具有相同的数值。在执行完截短和带符号扩展操作后,这个int类型变量中将容纳一个有效的byte类型的值。

    applet模拟列出了一个超出byte类型有效范围的int类型值转换为byte类型时所发生的事情。 例如,imlnt变量的值为128 (0x00000080),它被转换为byte类型后,所得到的byte类型值为-128 (Oxffffff8O)。然后,当imlnt变量的值为-129 (Oxffffff7f)时.它被转换为byte类型后所得到的值为127 ( 0x0000007f )。

  • 相关阅读:
    [转载]Javascript:history.go()和history.back()的用法和区别
    微信商户平台,开通企业付款到用户功能
    使用ASP.Net WebAPI构建REST服务——客户端
    在WebAPI使用Session
    在asp.net一般应用程序中使用session
    Web Api Post注意事项
    WebAPI返回数据类型解惑
    c#中const与readonly区别
    sql之left join、right join、inner join的区别
    C#实现json的序列化和反序列化
  • 原文地址:https://www.cnblogs.com/mongotea/p/11980066.html
Copyright © 2020-2023  润新知