Java i++ 和 ++i 的字节码分析

时间:2024-01-24 12:32:03

一、描述

想必大家对i++;++i的问题一定不会陌生;例如:

int j=0;
for(int i=0;i<100;i++) {
  j=j++;
}
System.out.println("j="+j);

但是联系之前写的一篇 JAVA 连等赋值问题 的博客,原以为产生差别的原因是栈中的引用导致的,结果查看 class 字节码后发现不是,所以在这里再分析一下;

二、分析

1. ++i

int j, i = 0;
j = ++i;

使用 javap -v .class查看字节码;也可以使用 Jclasslib(一款 Class 文件的编辑器);

Code:
  stack=1, locals=3, args_size=1
    0: iconst_0          // 将0压入操作数栈
    1: istore_2          // 将0存入本地变量表2的位置
    2: iinc       2, 1   // 本地变量表位置2加1
    5: iload_2           // 载入本地变量表2位置到操作数栈
    6: istore_1          // 存入本地变量表位置1
    7: return
  LocalVariableTable:
    Start  Length  Slot  Name   Signature
        0       8     0  args   [Ljava/lang/String;
        7       1     1     j   I     // j 为本地变量表1
        2       6     2     i   I     // i 为本地变量表2

如图:

++i

所以最终结果是: i=1;j=1;

2. i++

int j, i = 0;
j = i++;

同样需要查看字节码;

Code:
  stack=1, locals=3, args_size=1
    0: iconst_0
    1: istore_2
    2: iload_2
    3: iinc       2, 1
    6: istore_1
    7: return
  LineNumberTable:
    line 69: 0
    line 70: 2
    line 73: 7
  LocalVariableTable:
    Start  Length  Slot  Name   Signature
        0       8     0  args   [Ljava/lang/String;
        7       1     1     j   I
        2       6     2     i   I

i++

所以最终结果是:i=1;j=0;

总结

  • 最终对比会发现 i++ 和 ++i,只有 iload_2 的位置不一样;使得最终回写到 j 位置的值不一样;
  • 文中字节码的含义是在《Java 虚拟机规范》中查找的;