i java 字节码_用java字节码解释i++和++i
先看4个题目:
①int i = 0;
i = i++;
②int i = 0;
i = ++i;
③int i = 0;
int j = 0;
j = i++ + i++;
④ int i = 0;
int j = 0;
j = i++ + i++ + i++;
每道题里的i和j都是多少?
用myeclipse测试,结果分别是①i = 0,②i = 1,③i = 2,j = 1,④i = 3,j = 3。
i++和++i的问题,困扰很多人。网上、书上的解释各种各样。现在通过分析字节码,来确定这两条语句究竟是怎样执行的。
先给出今天要用到的字节码的含义
Bytecode
Stack
before->after
Description
iconst_0
->0
Loads the int value 0 onto the stack
istore_1
value->
Store int value into variable 1
istore_2
value->
Store int value into variable 2
iinc
No change
Increment local variable #index by signed byte const
iload_1
->value
Loads an int value from variable 1
iadd
value 1,value 2->result
Adds 2 ints together
说明两点需要注意的地方:
①iinc操作是有参数的,但是在此忽略,简写为iinc,此操作对应于自加操作,并且该操作不对stack有任何改变;
②iadd操作过后只在stack中保留结果result。
接下来是四段程序主要的字节码:
①iconst_0 ②iconst_0 ③iconst_0 ④iconst_0
istore_1 istore_1 istore_1 istore_1
iload_1 iinc 1,1 iconst_0 iconst_0
iinc 1,1 iload_1 istore_2 istore_2
istore_1 istore_1 iload_1 iload_1
iinc 1,1 iinc 1,1
iload_1 iload_1
iinc 1,1 iinc 1,1
iadd iadd
istore_2 iload_1
iinc 1,1
iadd
istore_2
现在解释①。第一步在stack中存入一个int常量0;第二步把它赋值给第一个变量,即我们的i;第三步把第一个变量i的值存入到stack中;第四步在i自身的空间进行自加,而第三步存入到stack中的值没有变;第五步把第三步存入到stack中的值再赋值给第一个变量i。也就是说,i真的是进行自加了,但是被自己原来的值覆盖掉了。从这里我们可以看出,自加操作比赋值操作的优先级高。
再看②。和①比较起来,区别就在于,++i是先进行自加,然后把自加后的值存入到stack中,所以最后赋值给i的是1,不是0。
③呢?首先,③比前两个多了一个变量,但这不是重点。往下看,把第一个变量i的值(0)存入到stack中,i自加,再第一个变量i的值(1)存入到stack中,再自加。此时stack中有两个值了,0和1,进行加操作后的结果是1,然后赋值给第二个变量j。这里颠覆了我们以前被告知的,加的运算优先级比自加高。这就是困扰我们的,其实,只要把值读入到stack中,接下来就进行自加,只有得到了两个参数,才进行加操作。
来看④。前面都和③一样,只到进行了第一次加操作,得到的结果(1)保存在stack中,没有赋值给j,然后再次读入i的值(2)到stack,i自加,得到加操作的两个参数,1和2,进行第二次加操作的结果是3,赋值给j。
到此,问题都解决了。
i java 字节码_用java字节码解释i++和++i相关推荐
- java中字节码_聊聊Java的字节码
本文为作者原创,转载请注明出处(http://www.cnblogs.com/mar-q/)by 负赑屃 巴山楚水凄凉地,二十三年弃置身. 怀旧空吟闻笛赋,到乡翻似烂柯人. 沉舟侧畔千帆过,病树前头万 ...
- java将一个整数按字节输出_在java中的整数类型有四种,分别是 byte short int long 其中byte只有一个字节 0或1,在此不详细讲解。其他的三种类型如下:1、...
在java中的整数类型有四种,分别是 byte short int long 其中byte只有一个字节 0或1,在此不详细讲解. 其他的三种类型如下: 1. 基本类型:short 二进制位数:16 ...
- fileoutputstream 字节乱码_吃透Java IO:字节流、字符流、缓冲流
前言 有人曾问fastjson的作者(阿里技术专家高铁):"你开发fastjson,没得到什么好处,反而挨了骂背了锅,这种事情你为什么要做呢?" 高铁答道:"因为热爱本身 ...
- java字符串如何计算_关于Java:如何正确计算字符串字节?
包含特殊字符(例如?)的Java字符串在每个特殊字符中占用两个字节的大小,但是String length方法或使用从getBytes方法返回的字节数组获取其长度不会返回计数为两个字节的特殊字符. 如何 ...
- java 中文域名转码_转换java方法
java date String 类型相互转换 这种转换要用到java.text.SimpleDateFormat类 字符串转换成日期类型: 方法1: 也是最简单的方法 Date date=new D ...
- java 中文域名转码_转换java对象
数据解析 ●网络解析 Gson (一个Java序列化/反序列化库,可以将JSON和java对象互相转换) Jackson (Jackson可以轻松地将Java对象转换成json对象和xml文档,同样也 ...
- Java线程池状态判断源码_深入浅出Java线程池:源码篇
前言 在上一篇文章深入浅出Java线程池:理论篇中,已经介绍了什么是线程池以及基本的使用.(本来写作的思路是使用篇,但经网友建议后,感觉改为理论篇会更加合适).本文则深入线程池的源码,主要是介绍Thr ...
- 安卓java修改热点_修改Android源码实现连接指定BSSID的热点
1 概述 需要实现一个需求,Android手机A发射热点,获取BSSID,发送到另一台Android设备,在环境中存在多个同样SSID和密码的情况下,设备只会连接手机A. 1.1 概念 服务集识别码( ...
- java 集合反射_关于granite源码包CollectionUtil集合工具类获取集合反射类型、实例化各种集合类型HashSet/ArrayList等...
一.前言 基于granite源码包org.granite.util.CollectionUtil集合工具类,分别获取集合反射类型java.lang.reflect.Type.实例化newCollect ...
- java后端做教育视频网站源码_【Java并发面试点】看这一篇应该是够了
[Java并发面试点]看这一篇应该是够了 Java并发编程是Java后端.大数据开发面试必问项目之一,求职者务必掌握! Java并发面试点List 并发概念须知:进程与线程.同步与异步.并发与并行.阻 ...
最新文章
- Apache - AH00341
- python xmxl 无法启动_问题引发由于与GI相关的python脚本中的错误,Gnome终端无法启动...
- JAVA的23种设计模式
- jakarta ee_Jakarta EE 8状态
- java 获取service_Java service层获取HttpServletRequest工具类的方法
- Python入门8_方法,属性,迭代器
- javascript使用事件委托
- 阿里java规范_阿里Java规范
- 转:windows xp 安装MYSQL 出现Error 1045 access denied 的解决方法
- vue-admin自定义后台管理系统(二)之vue-cli3创建前端项目
- jQuery 5 条件选择器
- 可视化软件有哪些?各自的优缺点?
- 微信emoji表情包存入数据库报错处理
- 苹果手机需要清理垃圾吗?
- excel文件的工作表保护密码忘记了
- heic格式图片转为jpg格式 安装pyheif
- 当Godot游戏引擎遇上物联网,可以开出怎样的花
- 铝网初效过滤器及金属网过滤器的区别
- 整数规划 - 数学建模
- 我们在使用领英时有必要用领英精灵吗?
热门文章
- IE报告“存储空间不足,无法完成此操作”的原因
- ELK+logstash配置日志报警
- 阿里云centos7监控postgres9.6.6
- android ble 大小,Android BLE中传输数据的最大长度怎么破
- 终于解决“百年一遇”奇怪问题
- Oracle数据库中文乱码问题解决
- 解决一个Android Studio gradle的小问题
- 选择与Git进行提交意味着什么?
- 按值对对象属性进行排序
- 经常玩电脑正确的坐姿_疼痛科专家告诫,疼痛是疾病的信号,经常腰腿疼,可能是身体在呼救...