美文网首页
java 通过字节码指令分析 for循环、数组创建

java 通过字节码指令分析 for循环、数组创建

作者: zhy0324 | 来源:发表于2020-07-23 17:07 被阅读0次

前言

这篇文章是在我学习了JVM相关知识之后。明白了我们编写的代码,也就是.java文件会被翻译成.class字节码文件运行在虚拟中。.class文件中其实存放的就是jvm虚拟机认识的一条条指令,指挥着JVM做我们想要他做的事情。但是我们并不清楚,我们的代码最终成为了何种指令?

看次篇博文知识基础

  1. JVM的基础知识
  2. JVM的内存区域
  3. JAVA方法运行的虚拟机栈
  4. 字节码指令参考:https://cloud.tencent.com/developer/article/1333540

正文

下面就通过代码创建一个简单的for循环、创建数组来研究一下字节码

一个一个来看吧。

for循环

java代码

    public void method1(){
        for (int i = 0; i < 1000; i++) {
        }
    }

javap -c 反汇编字节码

  public void method1();
    Code:
       0: iconst_0                   加载一个静态常量0到操作数栈
       1: istore_1                   将操作数栈栈顶的数值加载到局部变量表下标为1的位置上
       2: iload_1                    将局部变量表下标为1的数值加载到操作数栈中
       3: sipush        1000         将常量1000加载到操作数栈
       6: if_icmpge     15           比较栈顶两个int类型数值的大小 ,当前者  大于等于  后者时,跳转。(跳出循环)
       9: iinc          1, 1         将局部变量表下标为1的数值自增1
      12: goto          2            跳转到指令2继续执行(开启循环)
      15: return
问题

这里这个if_icmpge 这个指令的解释有点争议,前者后者,到底是代码里的前者后者(i是前者,1000是后者),还是栈里数据的前者后者(这个就更分不清前后了,最好用栈顶栈底来说),让人搞不清。
经过我的研究,我将if_icmpge 的解释改为比较栈顶两个int类型数值的大小 ,当栈顶第二个数值(i) 大于等于 栈顶第一个数值(1000)时,跳转。(跳出循环),执行完此条命令栈顶的两个值会被清空

创建数组

java代码

    public void method2(){
        String[] array = {"0","1","2"};
    }

javap -c 反汇编字节码

  public void method2();
    Code:
       0: iconst_3                          将一个常量3加载到操作数栈当中
       1: anewarray     #2                  该指令首先从操作数栈中加载栈定数据(3),并创建一个大小为该数据的数组,并将该数组的对象引用放入操作数栈中
       4: dup                               拷贝一份栈顶的值,并将其压栈,例如栈顶的值刚开始为value,执行完为value,value
       5: iconst_0                          将数值为0的压入操作数栈中
       6: ldc           #3                  将String "0"的字符串引用压入操作数栈当中
       8: aastore                           执行数组值存放,下面会解释
       9: dup
      10: iconst_1
      11: ldc           #4                  // String 1
      13: aastore
      14: dup
      15: iconst_2
      16: ldc           #5                  // String 2
      18: aastore
      19: astore_1                          将栈顶的数据(数组array的引用)加载到局部变量表下标为1的位置
      20: return
关于aastore

可以参考:博客链接
第一个a表示数组中存放的数据类型,a是reference的意思。
第二个a表示array,表示这是一个数组操作。
store就是将元素存入数组了。
在使用这个aastore时,必须要先入栈数组引用,然后入栈下标index,然后入栈所需要存放的值。这是一种存放数组数据的标准。
可以看到真实的顺序是,先通过anewarray指令new出一个数组对象(array),并通过dup指令将数组array的引用拷贝了一份压入栈中,此时栈中有两个数组变量ints,然后入栈常量0,表示要操作数组array的下标,然后入栈String“0”的引用,表示要数组中要存放的数据。此时栈底到栈顶的顺序是:array(引用),array(引用),0,"0"。然后调用aastore,执行完清空栈,只留下一个栈底的ints的引用。然后继续执行。

相关文章

  • java 通过字节码指令分析 for循环、数组创建

    前言 这篇文章是在我学习了JVM相关知识之后。明白了我们编写的代码,也就是.java文件会被翻译成.class字节...

  • 创建类和数组实例的指令

    一、创建指令 虽然类实例和数组都是对象,但Java虚拟机对类实例和数组的创建与操作使用了不同的字节码指令: 1.创...

  • Android字节码插桩demo

    1. 基本概念 1.1 java字节码 Java字节码是Java虚拟机执行的一种虚拟指令格式。可通过javac 编...

  • Java并发机制的底层原理

    Java程序执行:Java代码→Java字节码→字节码被类加载器加载到JVM里,JVM执行字节码→转化为汇编指令在...

  • Java ByteCode

    什么是Java字节码指令?简而言之,Java字节码指令就是Java虚拟机能够听得懂、可执行的指令,可以说是Jvm层...

  • 彻底搞清楚Java并发 (二) 底层实现

    Java代码 -> Java字节码 -> 汇编指令(汇编指令是cpu指令的集合) Volatile Java语言提...

  • JVM-06

    switch-case的字节码指令: Java代码如下: 字节码指令如下: 结论是:switch-case 语句 ...

  • Java 虚拟机(一):Java 字节码

    Java 字节码 Java 字节码是 JVM 里面指令的型式, Java 的源码经过 Java 编译器会形成 Ja...

  • 03 Java字节码技术

    1 字节码角度分析 a++ Java代码 反编译Java代码 分析 iinc指令是直接在局部变量槽位slot上进行...

  • Java字节码

    参考链接:一文让你明白Java字节码 Java字节码 Java虚拟机字节码指令 Java号称是一门“一次编译到处运...

网友评论

      本文标题:java 通过字节码指令分析 for循环、数组创建

      本文链接:https://www.haomeiwen.com/subject/hurhlktx.html