详解 JVM 字节码(6)重载

作者: zidea | 来源:发表于2019-05-04 11:49 被阅读32次
jvm

栈帧

【图】


  • 我们程序就是一个交互的电影
    每一个线程都会有一个栈帧,栈帧本身是一种数据结构,封装了方法的局部变量表、动态链接信息、方法的返回值以及。在 JVM 调用方法无论方法返回值还是抛出异常都一定要返回到调用方。

  • 动态链接
    其实 class 文件是源代码经过编译后得到的字节码,学过编译原理都会知道,这个仅仅完成了一半的工作(词法分析、语法分析、语义分析、中间代码生成),接下来就是实际的运行了。而 Java 选择的是动态链接的方式,只有在用到某个类时(可能是类加载时候或者真正调用类的时候)才会将其加载进内存,而不是像C++那样使用静态链接:将所有类加载,不论是否使用到。

  • 符号引用:在常量池中 A 类保存 B 类的唯一个名字,当调用到 B 类的符号引用转换为直接引用。

  • 直接引用

    1. invokeinterface 调用接口在运行期决定的到底调用实现该接口的哪一个对象的特定方法
    1. invokestatic : 调用静态方法
    1. invokespecial : 调用自己私有方法和构造方法<int>,调用父类的方法
    1. invokevirtual : 调用虚方法,和多态紧密相关的,也是运行动态查找的过程。
    1. invokedanimc : 动态调用方法
public class ClientA {
    public static void test(){
        System.out.println("test invoked");
    }

    public static void main(String[] args) {
        test();
    }
}

静态调用
  • invokestaic 调用 ClientA 的 test 静态方法
  • 能够被 invokespecialinvokestatic 调用方法都是在解析阶段就可以确定。包括下面这些方法。
    • 父类方法
    • 静态方法
    • 私有方法
    • 构造方法
      以上 4 中情况为静态解析。为什么公有方法不是呢?因为公有方法可能被复写所以不能确定,以上 4 种方法也称非虚方法。
class A {}
class B extends A{}
class C extends B{}
public class ClientB {
    public void print(A a){
        System.out.println("A class");
    }
    public void print(B b){
        System.out.println("B class");
    }
    public void print(C c){
        System.out.println("C class");
    }

    public static void main(String[] args) {
        A b = new B();
        A c = new C();
        ClientB clientB = new ClientB();
        clientB.print(b);
        clientB.print(c);
     }
}
A class
A class

方法的静态分派,用于 A 声明了 b ,所以 A 就是 b 的静态类型,而 b 的实际类型是 B 类型(也就是 b 的指向类型)。
b 的静态类型和实际类型,静态类型是不会改变的。即使强转也不会改变的 b 的静态类型。而实际类型是可以发生变化。这也是 JVM 对 java 多态实现的底层支持。
调用 print 的对象 clientB 这是在编译中已经确定,方法的重载对于 JVM 是一种静态行为,根据对象的静态类型来决定调用哪一个对应的方法。


字节码

相关文章

  • 详解 JVM 字节码(6)重载

    栈帧 【图】 栈 帧我们程序就是一个交互的电影每一个线程都会有一个栈帧,栈帧本身是一种数据结构,封装了方法的局部变...

  • JVM

    JVM 基础-类字节码详解 多语言编译为字节码在 JVM 运行 Java 字节码文件-- Class文件的结构属性...

  • JVM知识精粹

    1.jvm执行字节码文件 流程:jvm通过类加载器加载字节码文件----字节码校验器---翻译字节码(解释执行,反...

  • Java并发机制的底层原理

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

  • Java并发机制的底层实现原理

        Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为...

  • 详解 JVM 字节码 (1)

    在开始分析 class 字节码前我们先补一补一些基础知识,帮助我们更好地了解 jvm 是如何执行字节码的。大家可能...

  • 详解 JVM 字节码(3)

    版本信息 上一次我们分析前 4 个字节为魔数,继续向下数 4 字节为版本号信息(前两个字节表示此版本号,后两个字节...

  • 详解 JVM 字节码(2)

    什么是字节码,为什么需要字节码编译 JVM 编译成机器码, 我们看一看 Java 编译过程 java 源码 编译为...

  • 详解 JVM 字节码(Four)

    访问标志 访问标志信息包括该 Class 文件是类还是接口,是否被定义成 public,是否是 abstract,...

  • 详解 JVM 字节码(8)

    字节码的执行方式,程序执行有两种是编译执行和解释执行,JIT 编译产生本地代码生成机器码来执行。现在的 JVM 解...

网友评论

    本文标题:详解 JVM 字节码(6)重载

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