从字节码角度解析Java中i++和++i原理

Java中i++和++i原理解析

1. 直接上代码:

public class Test {
	public static void main(String[] args) {
		int i = 0,j = 0;
		i=i++;
		j=++j;
		System.out.println(i);
		System.out.println(j);
	}
}

2. 执行结果

0
1

3. 反汇编class文件输出:

javac Test.java
javap -c Test.class >> Test_class_compile.txt
Compiled from "Test.java"
public class Test {
  public Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0
       1: istore_1
       2: iconst_0
       3: istore_2
       4: iload_1
       5: iinc          1, 1
       8: istore_1
       9: iinc          2, 1
      12: iload_2
      13: istore_2
      14: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      17: iload_1
      18: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
      21: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      24: iload_2
      25: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
      28: return
}

4. 字节码执行过程解释

  • 下面我们对主函数中主要字节码进行逐行分析,主要针对程序执行过程中程序计数器、局部变量表、操作栈的变化情况来描述程序执行过程,其中程序计数器记录字节码执行偏移量
  • 执行偏移地址为0的指令时:

执行偏移地址为0的指令时

  • 执行偏移地址为1的指令时:

执行偏移地址为1的指令时

  • 由于2~3字节码执行任务与0~1相同,这里不再赘述,直接进入偏移地址4的指令执行状态
  • 执行偏移地址为4的指令时:

执行偏移地址为4的指令时

  • 执行偏移地址为5的指令时:

执行偏移地址为5的指令时

  • 执行偏移地址为8的指令时:

执行偏移地址为8的指令时

  • 执行偏移地址为9的指令时:

执行偏移地址为9的指令时

  • 执行偏移地址为12的指令时:

执行偏移地址为12的指令时

  • 执行偏移地址为13的指令时:

执行偏移地址为13的指令时

  • 因此最终i的值为0,j的值为1

5. 总结

  • i=i++的过程实际上就是先加载i到操作栈中,然后再执行++运算,即直接对局部变量表中i的值+1,然后直接将栈顶的值赋值给局部变量表中i的位置
  • j=++j的过程实际上就是先对局部变量表中的j的值+1,然后将局部变量j的值加载到操作栈中,最后将栈顶元素赋值给局部变量j,因此j=++j++j是等价的,因为压栈和出栈是连续的两个过程,即什么都没改变

6. 推广

  • 同理,如表达式(a++ + a--),假设初始时a=10,那么此表达式执行过程实际上就是先加载局部变量a的值到操作栈中,然后++对局部变量表中a的值直接+1,根据运算符优先级,然后再次加载a的值到栈中(此时a值为11),然后--对局部变量表中a的值直接-1,最后才进行加法运算+,即直接将操作栈顶两个与元素相加(此时操作栈中元素为1110),故最后此表达式的结果为21

7. 参考资料

《深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)》

End~

发布了22 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/TomAndersen/article/details/104259299