`

i++, ++i 原理

 
阅读更多
 最近网上看到一个面试题目是关于i++和++i,对于i++ 和++i 很多人都知道是不一样的,i=i++ 和 i=++i, 未必有人知道其中的奥妙,看了很多文章关于i++和++i的区别,都没有指出其中不一样的根本原因。有人说i++是线程安全的,有人说不是的,如果不是的那原因是什么呢?
我们先看下面一个例子
public class Test {
	
	public static void main(String[] args) {
		int i=0;
		i=i++;
		
		int j=0;
		j=++j;
	}
}
 
javap是jdk自带的一个工具,可以反编译,也可以查看java编译器生成的字节码, 通过查看字节码, 我们可以知道java代码在JVM中的运行过程
-l               输出行和变量的表

-public          只输出public方法和域

-protected       只输出public和protected类和成员

-package         只输出包,public和protected类和成员,这是默认的

-private         输出所有类和成员

-s               输出内部类型签名

-c               输出分解后的代码,例如,类中每一个方法内,包含java字节码的指令,

-verbose         输出栈大小,方法参数的个数  
 
java编译器输出的指令流,基本上是基于栈的指令集架构,指令流里面的指令大部分都是零地址指令,他们依赖操作数栈进行工作。
运行 javap -verbose Test,
public static void main(java.lang.String[]);
Code:
 Stack=1, Locals=3, Args_size=1
 0:   iconst_0  //首先,执行偏移地址为0的地址,把0入栈(栈顶=0),
 1:   istore_1   //把栈顶的值放到局部变量1中,即i中(i=0,栈顶=0)
 2:   iload_1  //把局部变量1的值,即0入栈,也就是说此时栈顶的值是0(i=0,栈顶=0)
 3:   iinc    1, 1 //把局部变量1,也就是i,增加1,这个指令不会导致栈的变化,i此时变成1了(i=1,栈顶=0)
 6:   istore_1  //把栈顶的值放到局部变量1中,即i中,栈顶的值是0,此时(i=0,栈顶=0)
 7:   iconst_0  //把0入栈(栈顶=0)
 8:   istore_2  //把栈顶的值放到局部变量2中,即j中(j=0,栈顶=0)
 9:   iinc    2, 1 //把局部变量2,也就是j,增加1,这个指令不会导致栈的变化,j此时变成1了
 12:  iload_2  //把局部变量2的值,即1入栈,此时(j=1,栈顶=1)
 13:  istore_2  //把栈顶的值放到局部变量2中,即j中(j=1)
 14:  return
LineNumberTable:
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics