写在前面
最近闲暇时间在研究jvm虚拟机原理,所以把日常看到的、学习到的记录下来,这篇文章比较简单,主要是基于上篇文章简单了解下i++和++i的区别
实例
直接上代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| public int iinc(){ return a++; } public int inci(){ return ++a; }
public int iinc(); descriptor: ()I flags: ACC_PUBLIC Code: stack=4, locals=1, args_size=1 0: aload_0 1: dup 2: getfield #8 // Field a:I 5: dup_x1 6: iconst_1 7: iadd 8: putfield #8 // Field a:I 11: ireturn LineNumberTable: line 32: 0 LocalVariableTable: Start Length Slot Name Signature 0 12 0 this Ljavp/JapTest;
public int inci(); descriptor: ()I flags: ACC_PUBLIC Code: stack=3, locals=1, args_size=1 0: aload_0 1: dup 2: getfield #8 // Field a:I 5: iconst_1 6: iadd 7: dup_x1 8: putfield #8 // Field a:I 11: ireturn LineNumberTable: line 35: 0 LocalVariableTable: Start Length Slot Name Signature 0 12 0 this Ljavp/JapTest;
|
仔细对比可以发现,两个方法的5、6、7三行指令发生了顺序上的变化。所以i++是先拷贝一份i的值,然后对栈顶的i的副本进行加一,随后将副本i弹出,返回i。++i则是先对i进行加1,然后再拷贝,再弹出,再返回。
其他:根据上面这些指令也可以发现多线程操作中这两个方法不安全的地方,不同线程在不同栈对同一对象执行操作,getfield和putfield都可能会覆盖对方。所以需要加锁。