JVM学习笔记14-方法的静态和动态分派

1.6方法的静态分派

代码示例如下:

public class MyTest5 {

    public void test(Father father){
        System.out.println("father");
    }
    public void test(Son son){
        System.out.println("son");
    }
    public void test(GrandPa grandPa){
        System.out.println("grandPa");
    }



    public static void main(String[] args) {
        GrandPa g1 = new Father();
        GrandPa g2 = new Son();

        MyTest5 test5 = new MyTest5();

        test5.test(g1);
        test5.test(g2);
    }

}

class GrandPa{

}

class Father extends GrandPa{

}

class Son extends Father{

}

输出结果为:

grandPa
grandPa

原因是:
方法的重载是一种静态行为,编译期就可以完全确定

GrandPa g1 = new Father();
以上代码,g1的静态类型是GrandPa,而g1的实际类型(真正指向的类型)是Father

综上可得这样一个结论:
变量的静态类型是不会发生变化的,而变量的实际类型则是可以发生变化的(多态的一种体现)

1.7方法的动态分派

方法的动态分派涉及到一个重要的概念—方法接收者
invokevirtual字节码指令的多态查找流程

  • 从子类到父类逐级向上寻找操作数栈顶的第一个元素所指向的对象的实际类型
  • 从实际类型中找到特定的方法(方法名是否一致,是否返回值,返回类型是否一致)
  • 校验方法调用权限,如满足则调用
  • 如未找到对应的方法则抛出方法不存在异常NoSuchMethodException
public class MyTest6 {

    public static void main(String[] args) {
        Fruit apple = new Apple();

        Fruit orange = new Orange();

        apple.test();
        orange.test();

        apple = new Orange();
        apple.test();
    }

}

class Fruit{
    public void test(){
        System.out.println("Fruit");
    }
}

class Apple extends Fruit{
    @Override
    public void test(){
        System.out.println("Apple");
    }
}

class Orange extends Fruit{
    @Override
    public void test(){
        System.out.println("Orange");
    }
}

输出结果:

Apple
Orange
Orange


比较方法重载(overload)与方法重写(overwrite),我们可以得到这样一个结论:

  • 方法重载是静态的,是编译器行为
  • 方法重写是动态的,是运行期行为

1.6虚方法表

  • 针对于方法调用动态分配的过程, JVM会在类的方法区中创建一个虚方法表的数据结构(virtual method table)—vtable
  • 针对于invokeinterface指令来说, JVM会创建一个叫做接口方法表的数据结构(interface method table)–itable

其中

  • vtable 存放的是每个方法的实际入口调用地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值