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++问题分析的更多相关文章

  1. Java中ArrayList源码分析

    一.简介 ArrayList是一个数组队列,相当于动态数组.每个ArrayList实例都有自己的容量,该容量至少和所存储数据的个数一样大小,在每次添加数据时,它会使用ensureCapacity()保 ...

  2. Java中json工具对比分析

    Java中几个json工具分析 1, 环境 JDK1.6+IDE(IntelliJ IDEA)+windowsXP+GBK编码 2,分析对象 jackson1.8.2 http://jackson.c ...

  3. Eclipse中的快捷键快速生成常用代码(例如无参、带参构造,set、get方法),以及Java中重要的内存分析(栈、堆、方法区、常量池)

    (一)Eclipse中的快捷键:  ctrl+shift+f自动整理选择的java代码 alt+/ 生成无参构造器或者提升信息 alt+shift+s+o 生成带参构造 ctrl+shift+o快速导 ...

  4. 大杂烩 -- Java中Iterator的fast-fail分析

    基础大杂烩 -- 目录 Java中的Iterator非常方便地为所有的数据源提供了一个统一的数据读取(删除)的接口,但是新手通常在使用的时候容易报如下错误ConcurrentModificationE ...

  5. Java中的<< 和 >> 和 >>> 分析理解

    Java中的<< 和 >> 和 >>> 详细分析 <<表示左移移,不分正负数,低位补0: 注:以下数据类型默认为byte-8位 左移时不管正负,低 ...

  6. Java中I/O的分析

    Java中I/O的原理: 在java程序中,对于数据的输入/输出操作以”流“的方式进行的. 流是内存中一组有序数据序列 Java将数据从源读入到内存当中,形成了流,然后这些流可以写到目的地. Java ...

  7. Java中关于“=”和“==”的分析

    Java中变量分为普通原始变量(int char float等)和对象 一"=" (1)普通原始变量 普通原始变量的声明和赋值语句例如以下 int a=3; int b=a; 此时 ...

  8. Java中Iterator的fast-fail分析

    1.fail-fast简介 fail-fast机制是java集合(Collection)中的一个错误机制.当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件. 例如:当某一个线 ...

  9. Java中的递归原理分析

    解释:程序调用自身的编程技巧叫做递归.        程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明中有直接或间接调用 ...

随机推荐

  1. 封装AFNetworking

    用了一下AFNetworking感觉比ASIHttprequest 真心好用一些,因为我还是个初学者吧,很多ASIHttprequest 的功能还没有用到,与ASIHttprequest 不用的是AF ...

  2. MySQL中阻塞

    因为不同锁之间的兼容性关系,在有些时刻一个事务中的锁需要等待另一个事务中的锁释放它占有的资源,这就是阻塞.阻塞不是一件坏事,是为了保证事务可以并发并且正常的运行 在InnoDB存储引擎中,参数inno ...

  3. Django 请求生命周期【图示】

    Django 请求生命周期

  4. PHPExcel实现上传excel文件导入数据库

            项目中需要批量导入数据,感觉这个需求以后也会经常用,必须总结分享下: 引入jquery的第三方表单插件: <scripttype="text/javascript&qu ...

  5. yum命令的实例

    1) 自定义yum仓库:createrepo 2) 自定义repo文件 3) 使用yum命令安装httpd软件包(在这里需要强调一点,本身执行yum.repos.d时,文件里面是有自带的yum源的,需 ...

  6. 前端基础-html(3)

    一.列表标签 1.ul(无序列表)标签 ul(unordered list)无序列表,ul下的子元素只能是li(list item),如下示例: <ul> <li>第一项< ...

  7. python中的标识符长度能有多长

    在python中,标识符可以还是任意长度.此外,我们在命名标识符时还必须遵守以下规则 1 只能以下划线或者A-Z/a-z中字母开头 2 其余部分可以使用A-Z/a-z/0-9 3 区分大小写 4 关键 ...

  8. MySQL数据库(3)_MySQL数据库表记录操作语句

    附: MYSQL5.7版本sql_mode=only_full_group_by问题 .查询当前sql_mode: select @@sql_mode .查询出来的值为: set @@sql_mode ...

  9. extern "C" 有关问题

    之前帮老板编译一个库的代码,遇到了一些问题,后来发现问题出现在extern "C"语法上. 1. C/C++语法extern 关键字 extern是C/C++语言中表明函数和全局变 ...

  10. 17 南宁区域赛 F - The Chosen One 【规律】

    题目链接 https://nanti.jisuanke.com/t/19972 题意 给出一个n 然后将 n 个数 标号为 1 -> n 按顺序排列 每次抽掉 奇数位的数 然后求最后剩下那个数字 ...