JAVA基础:a++与++a的区别

a++与++a

  • 首先在java中a++和++a都属于自增运算符
    关于区别我们来看下边程序:
     public static void main(String[] args) {
             int a = 0;
             System.out.println("初始化a:"+a);
             int b = a++;
             System.out.println("a++运算:"+b);
             System.out.println("a++运算结束,a值:"+a);
             a = 0;
             System.out.println("初始化a:"+a);
             int c = ++a;
             System.out.println("++a运算:"+c);
             System.out.println("++a运算结束,a值:"+a);
         }
    
    我们将a++赋值给b,将++a赋值给c,方便打印
    程序输出结果:
      初始化a:0
      a++运算:0
      a++运算结束,a值:1
      初始化a:0
      ++a运算:1
      ++a运算结束,a值:1
    
    从输出结果可以看出:
    • a++运算输出为0,但是经过a++后,a的值最终为1
    • ++a运算输出为1,经过a++后,a的值最终为1
    所以可以得出:
    • a++是先进行取值,然后进行自增运算.
    • ++a是先进行自增运算,然后进行取值.
  • 为知其然知其所以然,我们使用IDEA打开对应的ByteCode
      public static main([Ljava/lang/String;)V
         L0
          LINENUMBER 10 L0
          ICONST_0
          ISTORE 1
         L1
          LINENUMBER 11 L1
          GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
          ILOAD 1
          IINC 1 1
          INVOKEVIRTUAL java/io/PrintStream.println (I)V
         L2
          LINENUMBER 12 L2
          ICONST_0
          ISTORE 1
         L3
          LINENUMBER 13 L3
          GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
          IINC 1 1
          ILOAD 1
          INVOKEVIRTUAL java/io/PrintStream.println (I)V
         L4
          LINENUMBER 24 L4
          RETURN
         L5
          LOCALVARIABLE args [Ljava/lang/String; L0 L5 0
          LOCALVARIABLE a I L1 L5 1
          MAXSTACK = 2
          MAXLOCALS = 2
    
    大致来说:L0是初始化变量a为0,L1体现的是a++时的操作;L2将a的值再次初始化为0,L3为++a时的操作
    从对应的字节码中我们可以观察到几个关键的指令:
    • ICONST_0 : 将常量 0 压入操作数栈中
    • ISTORE 1 : 弹出操作数栈栈顶元素,保存到局部变量表第1个位置
    • ILOAD 1 :第1个变量压入操作数栈
    • IINC 1 1 : 局部变量表中的第1位的变量a执行自增操作
    从对应的字节码可以看出:
    • a++是先ILOAD 1,后IINC 1 1
    • ++a是先IINC 1 1,后ILOAD 1
    恍然大悟.与上方我们用程序得出的结果相匹配