package club.interview.base;

/**
* ++i 先"++"后赋值
* i++ 先赋值后"++"
* i++ 局部变量表的值会改变,但是操作数栈并不会变,后面需要使用会把局部变量表中的值放入操作数栈
* <p>
* --- 参考内容 (你值得拥有)
* * jvms文档
* * jclasslib 工具插件
*
* @author QuCheng on 2020/7/6.
*/
public class IAdd { /**
* i++是先赋值后++ ++i是先++后赋值
* 计算机是逐个击破,不是先搜索所有运算法
* 0 iconst_2
* 1 istore_1
* 2 iload_1 栈 [2]
* 3 iinc 1 by 1
* 6 iload_1 栈 [3,2]
* 7 iadd 栈 [5]
* 8 iinc 1 by 1
* 11 iload_1 [4,5]
* 12 iadd [9]
* 13 iload_1 [4,9]
* 14 iadd [13]
* 15 istore_1 []
* 16 getstatic #2 <java/lang/System.out>
* 19 iload_1 [13]
* 20 invokevirtual #3 <java/io/PrintStream.println> []
* 23 return
*/
private void sunmmary() {
int i = ;
// // 2 3 4 4
i = i++ + i + ++i + i;
System.out.println(i);
} /**
* 局部变量表 -> lvt
* 0 iconst_0 将0push到栈顶
* 1 istore_1 将0从栈顶弹出 lvt(index1 = 0)
* 2 iinc 1 by 1 栈空 lvt(index1 = 1)
* 5 getstatic #2 <java/lang/System.out>
* 8 iload_1 栈顶为1 lvt(index1 = 1)
* 9 invokevirtual #3 <java/io/PrintStream.println>
* 12 return
*/
private void step1() {
int i = ;
i++;
System.out.println(i);
} /**
* 0 iconst_0 将常量0放入操作数栈栈顶 栈顶为0
* 1 istore_1 将栈顶的int元素赋值给局部变量表第1个位置(弹出)| 栈空 局部变量表index1为0
* 2 iload_1 将局部变量表第1个位置的值push到操作数栈栈顶 | 栈顶为0 局部变量表index1为0
* 3 iinc 1 by 1 将第一个位置的局部变量加1(by 1) | 0-> 1 栈顶为0 局部变量表index1为1
* 6 istore_1 同上(赋值) | 栈空 局部变量表index1为0 (被覆盖)
* 7 getstatic #2 <java/lang/System.out>
* 10 iload_1 读取局部变量1位置到栈顶 | 栈顶为0 局部变量表index1为0
* 11 invokevirtual #3 <java/io/PrintStream.println> 打印是将局部变量表中的值放入操作数栈栈顶,然后读取
* 14 return
*/
private void test2() {
int i = ;
i = i++;
System.out.println(i);
} /**
* 0 iconst_0
* 1 istore_1
* 2 iload_1 (理解的关键点 把局部变量表中index1位置的值放入栈顶 为了之后赋值)
* 3 iinc 1 by 1
* 6 istore_2 lvt(index2 = 0)
* 7 getstatic #2 <java/lang/System.out>
* 10 iload_1 将lvt(index1 = 1) 放入栈顶
* 11 invokevirtual #3 <java/io/PrintStream.println>
* 14 getstatic #2 <java/lang/System.out>
* 17 iload_2 将lvt(index2 = 0) 放入栈顶
* 18 invokevirtual #3 <java/io/PrintStream.println>
* 21 return
*/
private void step3() {
int i = ;
int j;
j = i++;
System.out.println(i);
System.out.println(j);
} private void step4() {
int i = ;
int j;
j = ++i;
System.out.println(i);
System.out.println(j);
} public static void main(String[] args) {
IAdd i = new IAdd();
i.sunmmary();
}
}

i++ & ++i不看字节码是真的难懂的更多相关文章

  1. [原创]ASM动态修改JAVA函数之函数字节码初探

    ASM是非常强大的JAVA字节码生成和修改工具,具有性能优异.文档齐全.比较易用等优点.官方网站:http://asm.ow2.org/ 要想熟练的使用ASM,需要对java字节码有一定的了解,本文重 ...

  2. class字节码结构(一)(字节码结构和字节常量池的结构)

    <Java虚拟机原理图解> 1.1.class文件基本组织结构 关于变量的几个叫法: 局部变量/全局变量:很好区分根据所在位置. 类变量:静态的全局变量. 类常量:全局的final修饰的变 ...

  3. Python 字节码bytecode

    字节码bytecode python把源码文件编译成字节码文件,存放在__pycahe子目录内,用.pyc结尾.之后如果不再修改源码文件,运行时则使用*.pyc文件编译成机器码,这样不但运行速度快,而 ...

  4. IDEA字节码学习查看神器jclasslib bytecode viewer介绍

    转载来自:https://blog.csdn.net/w605283073/article/details/103209221 一.背景 很多人想学习Java反汇编后的字节码,但是一方面缺乏好的资料, ...

  5. 【Java虚拟机1】Java字节码文件格式入门

    第一次学习看字节码文件,这个对工作没什么用,但是会提升内功. 首先介绍两个IDEA插件以及使用: BinEd:以16进制格式查看class文件 使用方法:右键class文件,点击Open as bin ...

  6. 从字节码层面看“HelloWorld” (转)

    一.HelloWorld 字节码生成 众所周知,Java 程序是在 JVM 上运行的,不过 JVM 运行的其实不是 Java 语言本身,而是 Java 程序编译成的字节码文件.可能一开始 JVM 是为 ...

  7. 从 HelloWorld 看 Java 字节码文件结构

    很多时候,我们都是从代码层面去学习如何编程,却很少去看看一个个 Java 代码背后到底是什么.今天就让我们从一个最简单的 Hello World 开始看一看 Java 的类文件结构. 在开始之前,我们 ...

  8. 从字节码看java类型转换【 深入理解 (T[]) new Object[size] 】

    我们都知道,java中对类型的检查是很严格的,所以我们平操作时,也往往很小心. 如题: (T[]) new Object[size],这种写法是一般我们是不会干的!但是有点经验的同学,还是会遇到这样写 ...

  9. 从字节码看java中 this 的隐式传参

    从字节码看java中 this 隐式传参具体体现(和python中的self如出一辙,但是比python中藏得更深),也发现了 static 与 非 static 方法的区别所在! static与非s ...

随机推荐

  1. Java 入门教程

    Java 入门教程 Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言. Java可运行于多个平台,如Windows, Mac OS,及其他多种UNIX版本的系统 ...

  2. .Net Core微服务入门全纪录(一)——项目搭建

    前言 写这篇博客主要目的是记录一下自己的学习过程,只能是简单入门级别的,因为水平有限就写到哪算哪吧,写的不对之处欢迎指正. 什么是微服务? 关于微服务的概念解释网上有很多... 个人理解,微服务是一种 ...

  3. cubic-bezier() 函数

    2020-03-13 cubic-bezier() 函数 ubic-bezier() 函数定义了一个贝塞尔曲线(Cubic Bezier). 贝塞尔曲线曲线由四个点 P0,P1,P2 和 P3 定义. ...

  4. FWT,FST入门

    0.目录 目录 0.目录 1.什么是 FWT 2. FWT 怎么做 2.1. 或卷积 2.2.与卷积 2.3.异或卷积 2.4.例题 3. FST 3.1. FST 怎么做 3.2.例题 1.什么是 ...

  5. 用turtle画蛇

    import turtle def drawSnake(rad,angle,len,nackrad): for i in range(len): turtle.circle(rad,angle) #画 ...

  6. range用法(倒序取值)

    range(4,-1,-1) #倒数取值 ''' start: 计数从 start 开始.默认是从 0 开始.例如range(5)等价于range(0, 5); stop: 计数到 stop 结束,但 ...

  7. Loadrunner12将fiddler跟踪文件转为脚本的后续处理事项

    之前一篇文章说过,Loadrunner12是支持将fiddler的跟踪文件.SAZ直接转成LR的脚本的,好多小伙伴都用了这个方法,但是生成脚本后用LR11运行的时候就出问题了,会发现runtime-s ...

  8. Java容器面试总结

    1.List,Set,Map三者的区别? List:用于存储一个有序元素的集合. Set:用于存储一组不重复的元素. Map:使用键值对存储.Map会维护与Key有关联的值.两个Key可以引用相同的对 ...

  9. 程序员Linux教程初窥入门-刘志敏-专题视频课程

    程序员Linux教程初窥入门-313人已学习 课程介绍        程序员Linux教程初窥入门主要针对初级入门程序员的课程,也是为后期学习其他课程的一个基础,Git.Maven.Jenkins.R ...

  10. 解决 React Native Android:app:validateSigningRelease FAILED 错误

    RN 运行的时候报这个错这咋办: