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. 【转】 通过VMLibrary在client partition上安装AIX全程实录

    现场实录,应该对新手有所帮助,因为本人就是新手...最近一段时间跟Linux无缘,都是在和PowerVM打交道,博文更新慢,不赖我,哈哈本文参考链接:AIX Migration with File-B ...

  2. 我的Android进阶之旅------>Android横竖屏切换总结

    在默认情况下当屏幕从竖评变到横屏时会触发 onConfigurationChanged 事件 在默认情况下会重新加载画面并显示和横屏一样的画面,这样会有2个问题,   * 布局问题,在竖屏 显示的布局 ...

  3. boost之实用工具

    1.noncopyable用于禁止复制和拷贝的类继承.声明拷贝和赋值函数为私有,将运行时的错误转化为编译期的错误. #include <iostream> #include <boo ...

  4. vue_router打包(webpack)

    把组件按组分块 有时候我们想把某个路由下的所有组件都打包在同个异步 chunk 中.只需要 给 chunk 命名,提供 require.ensure第三个参数作为 chunk 的名称: require ...

  5. 我的第三个Python小程序

    99乘法表: # Author: fansik # Description: 99 times table # method 1 num1 = 0 num2 = 0 while num1 < 9 ...

  6. ggplot2画图时标题无法居中的问题

    折腾了一天,终于好了.应该是版本的问题.在R3.2.2能居中(别问我为什么知道),在R3.3.2上就不能.解决方式如下: library(ggplot2) ggplot(data=mtcars, ae ...

  7. C#中的foreach和yield

    1. foreach C#编译器会把foreach语句转换为IEnumerable接口的方法和属性. foreach (Person p in persons) { Console.WriteLine ...

  8. Python基础(7)_闭包函数、装饰器

    一.闭包函数 闭包函数:1.函数内部定义函数,成为内部函数, 2.改内部函数包含对外部作用域,而不是对全局作用域名字的引用那么该内部函数成为闭包函数 #最简单的无参闭包函数 def func1() n ...

  9. PAT 天梯赛 L1-032. Left-pad 【字符串】

    题目链接 https://www.patest.cn/contests/gplt/L1-032 思路 要分两种情况处理 ①字符串长度 <= 填充长度 就在字符串前面输出(填充长度 - 字符串长度 ...

  10. IEEE802.11数据帧在Linux上的抓取 80211格式转8023帧格式

    转:http://blog.csdn.net/dog250/article/details/7749372 终于得到了梦寐的<802.11无线网络权威指南>,虽然是复印版本,看起来也一样舒 ...