美文网首页
2. Java字节码

2. Java字节码

作者: 轻轻敲醒沉睡的心灵 | 来源:发表于2021-07-22 15:44 被阅读0次

    1. 简单查看字节码

    上节说道Java是跨平台的语言,是因为运行Java的虚拟机JVM是能跨平台的,Java依赖于它,也就能跨平台了。我们写的Java源代码虚拟机不能识别,要经过编译后会变成.class文件,才能够被虚拟机加载。
    我们看一下java文件编译,以及字节码文件:

    • javac Demo.java
    • javap -c Demo.class

    Java源文件

    public class Demo {
        public static void test() {
            int n = 1;
            int m = 2;
            int t = (n + m) * 5;
            System.out.print(t);
        }
    }
    

    字节码

    字节码
    由上图可以看出,在字节码中,test()方法分步用很多指令(iconst、istore、iload)来操作数据。
    JVM 是一台基于栈的计算机器。
    每个线程都有一个独属于自己的线程栈(JVM Stack),用于存储栈帧(Frame)。每一次方法调用,JVM 都会自动创建一个栈帧。栈帧由操作数栈, 局部变量数组以及一个 Class 引用组成。test()方法中的局部变量都在同一栈针中。

    2. 字节码

    从上面的内容可以看出,字节码文件 就是把我们写的Java源文件编译成Jvm虚拟机可读的 一些指令集。
    Java bytecode 由单字节(byte)的指令组成,理论上最多支持 256 个操作码(opcode)。实际上 Java 只使用了200左右的操作码, 还有一些操作码则保留给调试操作。

    2.1 指令分类

    字节码中的指令,根据他们的性质,主要分为四个大类:

      1. 栈操作指令,包括与局部变量交互的指令 -- iconst、istore、iload等
      1. 程序流程控制指令
      1. 对象操作指令,包括方法调用指令 -- invokevirtual等
      1. 算术运算以及类型转换指令 -- iadd、imul等
    2.2 方法调用的指令:
      1. invokestatic,顾名思义,这个指令用于调用某个类的静态方法,这是方法调用指令中最快的一个。
      1. invokespecial, 用来调用构造函数,但也可以用于调用同一个类中的 private 方法, 以及可见的超类方法。
      1. invokevirtual,如果是具体类型的目标对象,invokevirtual 用于调用公共,受保护和package 级的私有方法。
      1. invokeinterface,当通过接口引用来调用方法时,将会编译为 invokeinterface 指令。
      1. invokedynamic,JDK7 新增加的指令,是实现“动态类型语言”(Dynamically Typed Language)支持而进行的升级改进,同时也是 JDK8 以后支持 lambda 表达式的实现基础。

    相关文章

      网友评论

          本文标题:2. Java字节码

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