浅谈a++和++a
很多初学java的朋友有时候很难区分a++与++a,包括我当初也是一样,傻傻很天真的以为两个东西是一样的,反正都是+1,那么今天我们就来说一下这个区别,哈哈!!!
先看两端代码:
public static void main(String[] args) {
int a = 127;
int c = a++;
System.out.println(c);
}
输出:127
public static void main(String[] args) {
int a = 127;
int c = ++a;
System.out.println(c);
}
输出:128
可以看出两个结果是不一样的,这时候如果你输出a 的话,前面a++的啊就是128,后面++a也是128 这就是所谓的a++ 是先赋值后+1,++a是先+1后赋值
我们也可以将两段代码的字节码文件反编译生成汇编代码分析一下
a++
Compiled from "xxx.java"
public class xxx {
public xxx();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: bipush 127
2: istore_1
3: iload_1
4: iinc 1, 1
7: istore_2
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: iload_2
12: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
15: return
}
分析:
public xxx(); // 默认无参构造
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: bipush 127 // 将127压入栈中
2: istore_1 // 弹出操作数栈栈顶元素,保存到局部变量表第1个位置, 索引1的位置就是127
3: iload_1 // 第1个变量压入操作数栈 ,栈顶元素
4: iinc 1, 1 // 将索引为1的局部变量按1递增 索引1= 128
7: istore_2 // 弹出操作数栈栈顶元素,保存到局部变量表第2个位置, 索引2的位置就是127 索引2相当于 c
8: getstatic #2 // 从常量池获取静态变量System.out Field java/lang/System.out:Ljava/io/PrintStream;
11: iload_2 // 第2个变量压入操作数栈
12: invokevirtual #3 // Method java/io/PrintStream.println:(I)V 调用实例方法 动态绑定
15: return
}
++a
public class xxx {
public xxx();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: bipush 127
2: istore_1
3: iinc 1, 1
6: iload_1
7: istore_2
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: iload_2
12: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
15: return
}
分析:
public xxx(); // 无参
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: bipush 127 // 将127压入栈中
2: istore_1 // 弹出操作数栈栈顶元素,保存到局部变量表第1个位置, 索引1的位置就是127
3: iinc 1, 1 // 将索引为1的局部变量按1递增 索引1= 128
6: iload_1 // 第1个变量压入操作数栈 栈顶元素
7: istore_2 // 弹出操作数栈栈顶元素,保存到局部变量表第2个位置, 索引2的位置就是128 索引2相当于 c
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: iload_2 // 第2个变量压入操作数栈 栈顶元素
12: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
15: return
}
我相信经过上面的分析应该大致可以理解一下这个问题了, 可以看出iinc指令执行的先后顺序,导致了最终结果的变化
今天就分析到这里了,有误的地方希望提出来,我改正,一起进步,加油!!!