java中i=i++问题分析
http://www.ticmy.com/?p=43
重点:局部变量表 和 操作数栈的执行过程。
使用javac编译后再使用javap -c Test反编译这个类查看它的字节码,如下(只摘取main方法):
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iload_1
3: iinc 1, 1
6: istore_1
7: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
10: iload_1
11: invokevirtual #3; //Method java/io/PrintStream.println:(I)V
14: return
这里,我从第0行开始分析(分析中【】表示栈,栈的底端在左边,顶端在右边):
0:将常数0压入栈,栈内容:【0】
1:将栈顶的元素弹出,也就是0,保存到局部变量区索引为为1(也就是变量i)的地方。栈内容:【】
2:将局部变量区索引为1(也就是变量i)的值压入栈,栈内容:【0】
3:将局部变量区索引为1(也就是常量i)的值加一,此时局部变量区索引为1的值(也就是i的值)是1。栈内容:【0】
6:将栈顶元素弹出,保存到局部变量区索引为1(也就是i)的地方,此时i又变成了0。栈内容:【】
7:获取常量池中索引为2所表示的类变量,也就是System.out。栈元素:【】
10:将局部变量区索引为1的值(也就是i)压入栈。栈元素:【0】
11:调用常量池索引为3的方法,也就是System.out.println
14:返回main方法
=================================================================
Java使用了中间缓存变量机制:
i=i++;等同于:
temp=i; (等号右边的i)
i=i+1; (等号右边的i)
i=temp; (等号左边的i)
而i=++i;则等同于:
i=i+1;
temp=i;
i=temp;
=================================================================
15: iload_2 //将局部变量区2号索引的变量i值0压入操作数栈
16: iinc 2, 1 //将局部变量区2号索引的值加1,操作数栈不发生变化
19: istore_2 //将栈顶的0弹出,赋给局部变量区2号索引的i
=================================================================
main 和 fremin 的 i 在各自 (运行时的当前栈帧<StackFrame>)的局部变量表<Local Variable Table>中,两个变量不一样。main调用fremin结束之后退栈,然而并没有改变main的栈帧的局部变量表里 i 的值。
i=i++;i++的汇编指令是(iinc 1,1),他只改变本地变量表的值,但是 i= 赋值的时候,操作数栈的栈顶还是0,存到本地变量表,又把slot1覆盖成0,所以得0.
iconst_0// 0
istore_1//slot 1 : i=0
iload_1 //取出0
iinc 1,1 //slot 1: i=1
istore_1// slot 1 = 0覆盖
iload_1 //println的还0
输出。
=================================================================
java中i=i++问题分析的更多相关文章
- Java中ArrayList源码分析
一.简介 ArrayList是一个数组队列,相当于动态数组.每个ArrayList实例都有自己的容量,该容量至少和所存储数据的个数一样大小,在每次添加数据时,它会使用ensureCapacity()保 ...
- Java中json工具对比分析
Java中几个json工具分析 1, 环境 JDK1.6+IDE(IntelliJ IDEA)+windowsXP+GBK编码 2,分析对象 jackson1.8.2 http://jackson.c ...
- Eclipse中的快捷键快速生成常用代码(例如无参、带参构造,set、get方法),以及Java中重要的内存分析(栈、堆、方法区、常量池)
(一)Eclipse中的快捷键: ctrl+shift+f自动整理选择的java代码 alt+/ 生成无参构造器或者提升信息 alt+shift+s+o 生成带参构造 ctrl+shift+o快速导 ...
- 大杂烩 -- Java中Iterator的fast-fail分析
基础大杂烩 -- 目录 Java中的Iterator非常方便地为所有的数据源提供了一个统一的数据读取(删除)的接口,但是新手通常在使用的时候容易报如下错误ConcurrentModificationE ...
- Java中的<< 和 >> 和 >>> 分析理解
Java中的<< 和 >> 和 >>> 详细分析 <<表示左移移,不分正负数,低位补0: 注:以下数据类型默认为byte-8位 左移时不管正负,低 ...
- Java中I/O的分析
Java中I/O的原理: 在java程序中,对于数据的输入/输出操作以”流“的方式进行的. 流是内存中一组有序数据序列 Java将数据从源读入到内存当中,形成了流,然后这些流可以写到目的地. Java ...
- Java中关于“=”和“==”的分析
Java中变量分为普通原始变量(int char float等)和对象 一"=" (1)普通原始变量 普通原始变量的声明和赋值语句例如以下 int a=3; int b=a; 此时 ...
- Java中Iterator的fast-fail分析
1.fail-fast简介 fail-fast机制是java集合(Collection)中的一个错误机制.当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件. 例如:当某一个线 ...
- Java中的递归原理分析
解释:程序调用自身的编程技巧叫做递归. 程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明中有直接或间接调用 ...
随机推荐
- 费马小定理 Fermat Theory
w 整数的质数次方和自身的差是是质数的倍数 费马小定理(Fermat Theory)是数论中的一个重要定理,其内容为: 假如p是质数,且Gcd(a,p)=1,那么 a(p-1)≡1(mod p).即: ...
- openvas-tutorial-for-beginners
https://jonathansblog.co.uk/openvas-tutorial-for-beginners
- 关于Java中的toString()方法
package c07; class ewq{ public String toString() { return "ppppppppp"; } public static voi ...
- (4.19)深入理解SQLSERVER的日志链
您真的理解了SQLSERVER的日志链了吗? 转自:https://www.cnblogs.com/lyhabc/p/3460272.html 先感谢宋沄剑给本人指点迷津,还有郭忠辉童鞋今天在QQ群里 ...
- Python替换文件内容
#!/usr/bin/env python import fileinput for line in fileinput.input('fansik',inplace=1): line = line. ...
- MySQL数据库(1)_MySQL数据库介绍与安装
一.数据库相关概念的简介 数据库(database,DB)是指长期存储在计算机内的,有组织,可共享的数据的集合.数据库中的数据按一定的数学模型组织.描述和存储,具有较小的冗余,较高的数据独立性和易扩展 ...
- Nginx -HTTP和反向代理服务器简单配置
from:http://blog.sina.com.cn/s/blog_6b64b6a701011feh.html Nginx官方测试能够支持5万并发连接,实际生产环境中可支持2-4万并发连接数. 在 ...
- Apache commons-io实现单文件读取和写入
Apache commons-io提供了很多类,这里只介绍FileUtils类. FileUtils类提供了一些操作文件对象的实用方法,包括文件的读取.写入.复制和比较等. 比如逐句读取和写入一个文件 ...
- 023_数量类型练习——Hadoop MapReduce手机流量统计
1) 分析业务需求:用户使用手机上网,存在流量的消耗.流量包括两部分:其一是上行流量(发送消息流量),其二是下行流量(接收消息的流量).每种流量在网络传输过程中,有两种形式说明:包的大小,流量的大小. ...
- 前端之CSS进阶
一.CSS属性操作 1.背景属性 常用: background-color 规定要使用的背景颜色 background-image 规定要使用的背景图像 background-repeat 规定如何重 ...