`
xdgj
  • 浏览: 36281 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

转载 Java i=i++问题

    博客分类:
  • Java
阅读更多

i++ ,++i,i=i++的问题


   int i=0;

      i=i++;

      结果i是多少?

      这是一个经常被提及的问题,答案一直五花八门。

      具体测试一下以说明问题:

      代码1:

  1. public class Test{
  2.     public static void main(String[] args){
  3.          int i=0;
  4.           i=i++;
  5.           System.out.println(i);
  6.      }
  7. }


     结果i依然是0.分析其反编译后的代码:

  1. public static void main(java.lang.String[]);
  2.    Code:
  3.    0:    iconst_0     //0放到栈顶
  4.    1:    istore_1    //把栈顶的值保存到局部变量1,也就是i中
  5.    2:    iload_1     //把i的值放到栈顶,也就是说此时栈顶的值是0
  6.    3:    iinc    1, 1 //注意这个指令,把局部变量1,也就是i,增加1,这个指令不会导致栈的变化,也就是说局部变量1,即i此时为1了。
  7.    6:    istore_1     //把栈顶的值(0)保存到局部变量1,也就是让i为0了,所以最后i为0
  8.    7:    getstatic    #2; //Field java/lang/System.out:Ljava/io/PrintStream;
  9.    10:   iload_1
  10.    11:   invokevirtual    #3; //Method java/io/PrintStream.println:(I)V
  11.    14:  return


值得注意到是i被修改了两次,第一次是i++;i变为1,最后一次是i=0;所以结果i是0

代码2:

  1. public class Test2{
  2.     public static void main(String[] args){
  3.          int i=0;
  4.          int j=0;
  5.           j=i++;
  6.           System.out.println(i);
  7.           System.out.println(j);
  8.      }
  9. }


这个结果肯定都知道,i是1,j是0.同样看反编译之后的代码:

  1. public static void main(java.lang.String[]);
  2.    Code:
  3.    0:    iconst_0
  4.    1:    istore_1     //i=0
  5.    2:    iconst_0
  6.    3:    istore_2     //j=0
  7.    4:    iload_1      //把i的值放到栈顶,也就是说此时栈顶的值是0
  8.    5:    iinc    1, 1 //局部变量1加1,也就是让i++了,此时i已经是1了,上面说过,此指令不会导致栈变化
  9.    8:    istore_2     //把栈顶的值(注意是0)存入局部变量2,也就是j中,所以j=0
  10.    9:    getstatic    #2; //Field java/lang/System.out:Ljava/io/PrintStream;
  11.    12:   iload_1
  12.    13:   invokevirtual    #3; //Method java/io/PrintStream.println:(I)V
  13.    16:   getstatic    #2; //Field java/lang/System.out:Ljava/io/PrintStream;
  14.    19:   iload_2
  15.    20:   invokevirtual    #3; //Method java/io/PrintStream.println:(I)V
  16.    23:  return

很明显可以看出,java是先把i的值取出来放到栈顶,我们可以认为是引入了第三个变量int k=i;然后i++,这时候i为1了,然后让j=k;也就是0.结论,i的++运算是在对j这个变量的赋值之前完成的。

代码3:

  1. public class Test3{
  2.     public static void main(String[] args){
  3.          int i=0;
  4.          int j=0;
  5.           j=++i;
  6.           System.out.println(i);
  7.           System.out.println(j);
  8.      }
  9. }


结果大家也都知道,i=1,j=1

看操作过程:

  1. public static void main(java.lang.String[]);
  2.    Code:
  3.    0:    iconst_0   
  4.    1:    istore_1    //i=0
  5.    2:    iconst_0
  6.    3:    istore_2     //j=0
  7.    4:    iinc    1, 1   //局部变量i加1,这时候i变成1了 。
  8.    7:    iload_1     //把i的值放到栈顶,栈顶的值是1
  9.    8:    istore_2    //j=1
  10.    9:    getstatic    #2; //Field java/lang/System.out:Ljava/io/PrintStream;
  11.    12:   iload_1
  12.    13:   invokevirtual    #3; //Method java/io/PrintStream.println:(I)V
  13.    16:   getstatic    #2; //Field java/lang/System.out:Ljava/io/PrintStream;
  14.    19:   iload_2
  15.    20:   invokevirtual    #3; //Method java/io/PrintStream.println:(I)V
  16.    23:  return

对比代码2和代码3,关键的差别就是iload_1   个iinc这两条指令的位置变了。

    最后把iinc指令介绍一下:

iinc

Operation

Forms

Operand Stack

Description


The iinc opcode can be used in conjunction with the wide instruction to access a local variable using a two-byte unsigned index and to increment it by a two-byte immediate value.

Notes

Increment local variable by constant 给局部变量加上一个常量的值


Format

iinc
index
const


iinc = 132 (0x84)No change   操作数栈无变化

The index is an unsigned byte that must be an index into the local variable array of the current frame(§3.6). The const is an immediate signed byte. The local variable at index must contain an

int

. The value const is first sign-extended to an

int

, and then the local variable at index is incremented by that amount.


原文地址http://piaoboqiu.blog.163.com/blog/static/123127827200910192122472/

 

分享到:
评论

相关推荐

    深入分析 Java I/O 的工作机制(转载)

    NULL 博文链接:https://liulijun-cn-2011.iteye.com/blog/1466273

    Java 开发实战1200例 (第I卷+第II卷+代码) -(两本书是PDF高清版-带超详细书签)

    Java 开发实战1200例 (第I卷+第II卷+代码) -(两本书是PDF高清版-带超详细书签) 特别好的一个资源!!! 本资源转载自网络,供学习研究之用,如用于商业用途,请购买正版,如有侵权,请联系我或CSDN删除。

    Java I/O, NIO and NIO.2

    本资源转载自网络,如有侵权,请联系上传者或csdn删除。 本资源转载自网络,如有侵权,请联系上传者或csdn删除。 本资源转载自网络,如有侵权,请联系上传者或csdn删除。

    Core Java Volume I--Fundamentals(10th) epub

    Core Java Volume I--Fundamentals(10th) 英文epub 第10版 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除

    OCA Java SE 8 Programmer I Certification Guide 无水印pdf

    OCA Java SE 8 Programmer I Certification Guide 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有...

    java nio 中文版

    这些新的I/O特性主要包含在java.nio软件包及其子包中,并被命名为New I/O(NIO)。通过本书,您将学会如何使用这些令人兴奋的新特性来极大地提升Java应用程序的I/O效率。  目录 前言 第一章 简介 第二章 缓冲...

    OCA Java SE 8 Programmer I Certification Guide mobi

    OCA Java SE 8 Programmer I Certification Guide 英文mobi 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除

    OCA Java SE 8 Programmer I Exam Guide Exams 1Z0-808 epub

    OCA Java SE 8 Programmer I Exam Guide Exams 1Z0-808 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除

    OCAOCP Java SE 7 Programmer I - II Study Guide(Exams 1Z0-803 - 1Z0-804) 无水印pdf

    OCAOCP Java SE 7 Programmer I - II Study Guide(Exams 1Z0-803 - 1Z0-804) 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除...

    java坦克大战 增强版 (源码)

    GameMain主类启动。...i键复活。 m键叛变。 x键使地图上所有经验珠,移动到自己上方。(一键吸宝) 功能很多,但是实现起来比较容易,适合新手学习。 本人资源,欢迎转载。转载时,麻烦注明来源,非常感谢。

    xmljava系统源码-drools:规则引擎drools集成springboot

    xml java系统源码 drools 版权声明:本文为CSDN博主「1Vincent」的原创文章,遵循 ...i++){ Order order = orderList.get(i); if (order.getAmout() <= 100){ order.setScore(0); addScore(order); }else if(order.

    JAVA-SSM农产品自主供销小程序+论文.zip

    系统功能分析 考虑到实际生活中在农产品自主... 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/Alonei6/article/details/137697963

    python入门教程.txt

    Python入门教程 超详细1小时学会Python 作者: 字体:[增加 减小] 类型:转载 本文适合有经验的程序员尽快进入Python世界.特别地,如果你掌握Java和Javascript,不用1小时你就可以用Python快速流畅地写有用的Python...

    springmybatis

    MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plan Old Java Objects,普通的Java对象)映射成数据库中的记录. orm工具的基本思想 无论是用过的hibernate,mybatis,你都可以法相他们有一个...

    Mobile Application Development Usability and Security 无水印pdf

    Mobile Application Development Usability and Security 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 ...本资源转载自网络,如有侵权,请联系上传者或csdn删除

    《21天学通Java》源代码

    我们将挑选特别优秀的作品转载在我们的网站上,或推荐至CSDN.NET等专业网站上发表,被发表的书评的作者将获得价值50元的博文视点图书奖励。    我们期待您的消息!  博文视点愿与所有爱书的人一起,共同学习,...

    spring源代码解析

    i++) { reader.loadBeanDefinitions(configLocations[i]); } } } //这里取得bean定义信息位置,默认的地方是/WEB-INF/applicationContext.xml protected String[] getDefaultConfigLocations() { if ...

    button按钮的四种监听及实例

     在button下加上如下代码android:onClick=skip(skip即为方法对应的名字,然后在java代码中在定义具体的方法)   android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height=...

    tomacat8.5 官方

    Apache Tomcat 8支持Java EE 7规范,包括Java Servlet 3.1、JSP 2.3、Java统一表达式语言EL 3.0等。Servlet 3.1最大的改进是实现了非阻塞式的I/O通信。这使得性能得到巨大的改进,数据可以通过ReadListener和...

    android logcat使用

    (hanchao3c Android开发者论坛原创,转载请注明) logcat是Android中一个命令行工具,可以用于得到程序的log信息。 logcat使用方法如下所示: logcat [options] [filterspecs] logcat的选项包括: -s 设置过滤器,...

Global site tag (gtag.js) - Google Analytics