欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

由++i和 i++想到的

程序员文章站 2022-06-07 16:32:22
...

1、例子程序,试想打印几,为什么?

public class db {
    public static void main(String[] args) {
        int i = 8;
        i = i++;
        System.out.println(i);
    }
}

 

 

public class db2 {
    public static void main(String[] args) {
        int i = 8;
        i = ++i;
        System.out.println(i);
    }
}

 2、对了,没错,如您所想。第一个打印8, 第二个打印9 。

 3、究其原理,从它们的字节码说起吧

第一个程序,main方法的字节码指令如下:

 i++

 0 bipush 8
 2 istore_1     //将栈顶int型数值存入第二个本地变量
 3 iload_1      //将第二个int型本地变量推送至栈顶
 4 iinc 1 by 1  // 局部变量自增指令:iinc
 7 istore_1     //  将栈顶int型数值存入第二个本地变量
 8 getstatic #2 <java/lang/System.out>
11 iload_1
12 invokevirtual #3 <java/io/PrintStream.println>
15 return

 第二个字节码指定如下:

++1

 0 bipush 8
 2 istore_1    //  将栈顶int型数值(8)存入第二个本地变量
 3 iinc 1 by 1 / 局部变量自增指令:iinc (8+1)
 6 iload_1     //将第二个int型本地变量推送至栈顶
 7 istore_1    //  将栈顶int型数值(9)存入第二个本地变量
 8 getstatic #2 <java/lang/System.out>
11 iload_1
12 invokevirtual #3 <java/io/PrintStream.println>
15 return

 比较可知,结果不同因为 “iinc 1 by 1 、iload_1”指令的顺序不同,一个是把局部变量表的值先自增(局部变量自增指令:iinc),iload_1 是将第二个int型本地变量推送至栈顶。另一个是将本地变量表变量+1后,压入栈顶,再存入第二个本地变量

 

4、常用字节码指令见https://www.cnblogs.com/tenghoo/p/jvm_opcodejvm.html