zoukankan      html  css  js  c++  java
  • 第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 )。

  • 相关阅读:
    101. Symmetric Tree(js)
    100. Same Tree(js)
    99. Recover Binary Search Tree(js)
    98. Validate Binary Search Tree(js)
    97. Interleaving String(js)
    96. Unique Binary Search Trees(js)
    95. Unique Binary Search Trees II(js)
    94. Binary Tree Inorder Traversal(js)
    93. Restore IP Addresses(js)
    92. Reverse Linked List II(js)
  • 原文地址:https://www.cnblogs.com/mongotea/p/11980066.html
Copyright © 2011-2022 走看看