在我们初学的时候经常会遇到++ --两个单目运算符,很多的时候我们听到关于这两个运算符的介绍都是说
i++就是先用原来的i做运算,再对i进行自加运算,但是却并没有深入理解它的内在机理。
我们知道在每一个变量都会有一块内存,在进行自加运算的时候,java会先在内存中开辟一个临时变量存储现在的值,再进行自加运算,在用临时变量作为运算。
在j=i++;中,先进行 int t=i;i=i+1;j=t; 在j=++j中,进行的是 int t=i+1;i=i+1;j=t;
所以我们知道为什么 i=i++;i的值是不变的了;因为在这个语句中,做的是:int t=i; i=i+1;i=t;
但是在c++中,因为编译器的运行机制不同,所以结果也不同,i=i++跟i++是一样的效果
一些参考的资料;
1:http://www.bitscn.com/plus/view.php?aid=20350
里面画得图很好,可以学习一下
2;这个是我在问人的时候有人贴的字节码,但是我没怎么看懂
public class JavaSampleAppend {
public static void main(String []args) {
int i = 1;
i = (i++) + (++i);
System.out.println(i);
}
}
/*
0: iconst_1 // 将int类型的常量值1推送到栈顶 1
1: istore_1 // 将栈顶抛出的数据赋值给第2个slot所在的int类型的本地变量中 1
2: iload_1 // 将第2个slot所在的int类型本地变量推送到栈顶 1
3: iinc 1, 1 // 将第2个slot所在的int类型的本地变量自加一 2
6: iinc 1, 1 // 将第2个slot所在的int类型的本地变量自加一 3
9: iload_1 // 将第2个slot所在的int类型本地变量推送到栈顶 3
10: iadd // 将栈顶变量和第二个变量相加,然后将结果放回栈顶 4
11: istore_1 // 将栈顶抛出的数据赋值给第2个slot所在的int类型的本地变量中 4 // 也就是说输出为4
12: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
15: iload_1
16: invokevirtual #3; //Method java/io/PrintStream.println:(I)V 19: return
*/
要是要查看字节码;
http://blog.csdn.net/lsbhjshyn/article/details/9329339
可以看这篇文章。指令是 javap -c 或者 javap -verbose
public static void main(String []args) {
int i = 1;
i = (i++) + (++i);
System.out.println(i);
}
}
/*
0: iconst_1 // 将int类型的常量值1推送到栈顶 1
1: istore_1 // 将栈顶抛出的数据赋值给第2个slot所在的int类型的本地变量中 1
2: iload_1 // 将第2个slot所在的int类型本地变量推送到栈顶 1
3: iinc 1, 1 // 将第2个slot所在的int类型的本地变量自加一 2
6: iinc 1, 1 // 将第2个slot所在的int类型的本地变量自加一 3
9: iload_1 // 将第2个slot所在的int类型本地变量推送到栈顶 3
10: iadd // 将栈顶变量和第二个变量相加,然后将结果放回栈顶 4
11: istore_1 // 将栈顶抛出的数据赋值给第2个slot所在的int类型的本地变量中 4 // 也就是说输出为4
12: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
15: iload_1
16: invokevirtual #3; //Method java/io/PrintStream.println:(I)V 19: return
*/
要是要查看字节码;
http://blog.csdn.net/lsbhjshyn/article/details/9329339
可以看这篇文章。指令是 javap -c 或者 javap -verbose