i++ 与 ++i 的从字节码层面看二者的区别
/**
* javap命令可以对class反汇编得到其字节码文件(此命令并不是jdk8开始的,只不过jdk8中对工具进行加强,增加了一些参数,可通过 javap -help了解)
*
* 注意:
* 字节码文件在虚拟机中是通过栈帧来保存指令的,也称为操作栈,是一个后入先出的栈。并不是针对寄存器的直接操作。
* 字节码执行引擎通过操作站获取指令。
*
* 这个测试同时验证了 ++i 和 i++的区别。
* ++i,在字节码层面,会先进行iinc,也就是执行自增,然后load变量
* i++,则是,先load变量,后自增(因为已经load,所以本次自增,并不会影响已经load的变量值)。
*
* @author zhuotao
*
*/
public class JavapTest {
/**
* 最简单的求和操作,javap反汇编得到的字节码如下:
Code:
0: iload_1 // 第一个int类型变量
1: iload_2 // 第二个int类型变量
2: iadd // 执行int类型的add操作
3: ireturn // 返回int类型
*
*/
public int add(int a, int b) {
return a+b;
}
/**
* 字节码如下:
* Code:
0: iload_1 // int类型变量
1: iconst_1 // int类型常量1
2: iadd // int类型add
3: ireturn // 返回
* @param a
* @return
*/
public int incr(int a) {
return a+1;
}
/**
* 字节码如下:
* Code:
0: iload_1 // int类型变量
1: iinc 1, 1 // iinc 局部变量自增 第一个“1” 表示int类型变量索引, 第二个“1”表示+1
4: ireturn // 返回
* @param a
* @return
*/
public int incr1(int a) {
return a++;
}
/**
* 用两个变量,来验证iinc的参数分别表示什么
* 字节码如下:
* Code:
0: iinc 2, 1 // “2”表示参数列表的第二个参数, "1"表示步长
3: iload_2 // load第二个int类型参数
4: ireturn // 返回load变量
*/
public int incr2(int a, int b) {
return ++b;
}
/**
* 这个方法字节码同incr2
* 字节码如下:
* Code:
0: iinc 1, 1
3: iload_1
4: ireturn
*/
public int incr3(int a) {
a++;
return a;
}
public static void main(String[] args) {
System.out.println(new JavapTest().incr1(2)); // return a++; 返回的是2,也就是先使用后加。
System.out.println(new JavapTest().incr2(0,2)); // return ++a; 返回的是3,也就是先加后使用。
System.out.println(new JavapTest().incr3(2));
}
}
i++ 与 ++i 的从字节码层面看二者的区别的更多相关文章
- 从字节码层面看“HelloWorld” (转)
一.HelloWorld 字节码生成 众所周知,Java 程序是在 JVM 上运行的,不过 JVM 运行的其实不是 Java 语言本身,而是 Java 程序编译成的字节码文件.可能一开始 JVM 是为 ...
- 从字节码层面看“HelloWorld”
一.HelloWorld 字节码生成 众所周知,Java 程序是在 JVM 上运行的,不过 JVM 运行的其实不是 Java 语言本身,而是 Java 程序编译成的字节码文件.可能一开始 JVM 是为 ...
- 从jvm字节码指令看i=i++和i=++i的区别
1. 场景的产生 先来看下下面代码展示的两个场景 @Testvoid testIPP() { int i = 0; for (int j = 0; j < 10; j++) { i = i++; ...
- i = i++ 在java字节码层面的分析
有这么一段代码: package zl.test; public class PcodeTest { /** * @param args */ public static void main(Stri ...
- 从字节码层面,解析 Java 布尔型的实现原理
最近在系统回顾学习 Java 虚拟机方面的知识,其中想到一个很有意思的问题:布尔型在虚拟机中到底是什么类型? 要想解答这个问题,我们看 JDK 的源码是无法解决源码的,我们必须深入到 class 文件 ...
- 字节码层面深入分析Java枚举类
枚举类的使用 定义一个简单的枚举类,其中包含若干枚举常量,示例如下: public enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY,THURSDAY, FR ...
- Tomcat 调优之从 Linux 内核源码层面看 Tcp backlog
前两天看到一群里在讨论 Tomcat 参数调优,看到不止一个人说通过 accept-count 来配置线程池大小,我笑了笑,看来其实很多人并不太了解我们用的最多的 WebServer Tomcat,这 ...
- 从JVM字节码执行看重载和重写
Java 重写(Override)与重载(Overload) 重写(Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变.即外壳不变,核心重写! 重写的 ...
- 从字节码指令看重写在JVM中的实现
Java是解释执行的.包含动态链接的特性.都给解析或执行期间提供了非常多灵活扩展的空间.面向对象语言的继承.封装和多态的特性,在JVM中是怎样进行编译.解析,以及通过字节码指令怎样确定方法调用的版本号 ...
随机推荐
- HDOJ 2092 整数解(2次方程整数解公式)
Problem Description 有二个整数,它们加起来等于某个整数,乘起来又等于另一个整数,它们到底是真还是假,也就是这种整数到底存不存在,实在有点吃不准,你能快速回答吗?看来只能通过编程. ...
- Javascript 操作select控件大全(新增、修改、删除、选中、清空、判断存在等)
1判断select选项中 是否存在Value="paraValue"的Item 2向select选项中 加入一个Item 3从select选项中 删除一个Item 4删除selec ...
- JavaScript中依赖注入详细解析
计算机编程的世界其实就是一个将简单的部分不断抽象,并将这些抽象组织起来的过程.JavaScript也不例外,在我们使用JavaScript编写应用时,我们是不是都会使用到别人编写的代码,例如一些著名的 ...
- 使用MyEclipse搭建java Web项目开发
转自:http://blog.csdn.net/jiuqiyuliang/article/details/36875217 首先,在开始搭建MyEclipse的开发环境之前,还有三步工具的安装需要完成 ...
- ButterKnife的使用
ButterKnife是一个Android View注入的库. 1.开始使用 1.1 配置Eclipse 在使用ButterKnife需要先配置一下Eclipse. 项目右键-Properties-J ...
- shell 脚本实现的守护进程
转自:http://blog.csdn.net/cybertan/article/details/3235722 转自:http://blog.sina.com.cn/s/blog_4c451e0e0 ...
- Cross-origin resource sharing--reference
Cross-origin resource sharing (CORS) is a mechanism that allows many resources (e.g., fonts, JavaScr ...
- 数据结构笔记01:编程面试过程中常见的10大算法(java)
以下是在编程面试中排名前10的算法相关的概念,我会通过一些简单的例子来阐述这些概念.由于完全掌握这些概念需要更多的努力,因此这份列表只是作为一个介绍.本文将从Java的角度看问题,包含下面的这些概念: ...
- Android实现真正的ViewPager【平滑过渡】+【循环滚动】!!!顺带还有【末页跳转】。
实现真正的ViewPager[平滑过渡]+[循环滚动]!!!顺带还有[末页跳转]. 首先呢, 我要对网上常见的3种ViewPager的循环滚动方法做个概述.急需看真正实现方法的同志请选择性忽略下面这一 ...
- Android UI WebView的使用:
Android UI WebView的使用: /** * @author smiling * @date 2016/10 */ 布局: <?xml version="1.0" ...