• 用java字节码解释i++和++i


    用java字节码解释i++和++i - tutuhatec的专栏 - 博客频道 - CSDN.NET

    先看4个题目:

    ①int i = 0;

        i = i++;

     

    ②int i = 0;

        i = ++i;

     

    ③int i = 0;

        int j = 0;

        j = i++ + i++;

     

    ④ int i = 0;

         int j = 0;

         j = i++ + i++ + i++;

    每道题里的i和j都是多少?

    用myeclipse测试,结果分别是①i = 0,②i = 1,③i = 2,j = 1,④i = 3,j = 3。

    i++和++i的问题,困扰很多人。网上、书上的解释各种各样。现在通过分析字节码,来确定这两条语句究竟是怎样执行的。

    先给出今天要用到的字节码的含义

    Bytecode

    Stack

    before->after

    Description

    iconst_0

    ->0

    Loads the int value 0 onto the stack

    istore_1

    value->

    Store int value into variable 1

    istore_2

    value->

    Store int value into variable 2

    iinc

    No change

    Increment local variable #index by signed byte const

    iload_1

    ->value

    Loads an int value from variable 1

    iadd

    value 1,value 2->result

    Adds 2 ints together

    说明两点需要注意的地方:

    ①iinc操作是有参数的,但是在此忽略,简写为iinc,此操作对应于自加操作,并且该操作不对stack有任何改变;

    ②iadd操作过后只在stack中保留结果result。

     

    接下来是四段程序主要的字节码:

    ①iconst_0        ②iconst_0        ③iconst_0       ④iconst_0

        istore_1            istore_1            istore_1           istore_1

        iload_1             iinc 1,1              iconst_0          iconst_0

        iinc 1,1             iload_1              istore_2           istore_2

        istore_1            istore_1            iload_1             iload_1

                                                          iinc 1,1             iinc 1,1

                                                          iload_1             iload_1

                                                          iinc 1,1             iinc 1,1

                                                          iadd                  iadd

                                                          istore_2            iload_1

                                                                                   iinc 1,1

                                                                                   iadd

                                                                                   istore_2

     

    现在解释①。第一步在stack中存入一个int常量0;第二步把它赋值给第一个变量,即我们的i;第三步把第一个变量i的值存入到stack中;第四步在i自身的空间进行自加,而第三步存入到stack中的值没有变;第五步把第三步存入到stack中的值再赋值给第一个变量i。也就是说,i真的是进行自加了,但是被自己原来的值覆盖掉了。从这里我们可以看出,自加操作比赋值操作的优先级高。

     

    再看②。和①比较起来,区别就在于,++i是先进行自加,然后把自加后的值存入到stack中,所以最后赋值给i的是1,不是0。

     

    ③呢?首先,③比前两个多了一个变量,但这不是重点。往下看,把第一个变量i的值(0)存入到stack中,i自加,再第一个变量i的值(1)存入到stack中,再自加。此时stack中有两个值了,0和1,进行加操作后的结果是1,然后赋值给第二个变量j。这里颠覆了我们以前被告知的,加的运算优先级比自加高。这就是困扰我们的,其实,只要把值读入到stack中,接下来就进行自加,只有得到了两个参数,才进行加操作。

     

    来看④。前面都和③一样,只到进行了第一次加操作,得到的结果(1)保存在stack中,没有赋值给j,然后再次读入i的值(2)到stack,i自加,得到加操作的两个参数,1和2,进行第二次加操作的结果是3,赋值给j。

     

    到此,问题都解决了。

  • 相关阅读:
    Jenkins
    ssh 免登录
    linux 远程执行命令
    Java WEB 笔记
    如何用新安装的jdk替换掉Linux系统默认jdk
    修改 File --> New 菜单内容
    java.security.NoSuchAlgorithmException: AES KeyGenerator not available
    JDK历史版本下载地址
    maven 核心概念
    spring boot: ConfigurationProperties
  • 原文地址:https://www.cnblogs.com/seven1979/p/4218685.html
Copyright © 2020-2023  润新知