【Java基础】多态性实现机制——静态分派与动态分派

本文深入探讨Java中多态性的实现机制,包括静态分派与动态分派的概念、应用场景及其实现原理。通过具体示例解释了如何在编译期和运行期确定方法调用的目标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文:多态性实现机制——静态分派与动态分派

方法解析:

      Class文件编译过程一切方法调用在Class文件里存储的只是符号引用,此特性给java带来强大的动态扩展能力,支持动态连接(在类运行期确定某些目标方法的直接引用),也有一部分方法的符号引用在类加载阶段或第一次使用时转为直接引用(静态解析)

 

静态解析:

       成立的前提:方法在程序真正执行前便有一个确定的在运行期不变的调用版本(调用目标在编译器进行编译时就确定了下来),这类方法的调用称为解析

编译期可知,运行期不可变的方法:

        静态方法:与类型直接关联;私有方法:外部不可访问

              均不可通过继承或别的方式重写出其他版本,适合类加载阶段进行解析

 

Java虚拟机提供四条方法调用字节指令:

         invokestatic:调用静态方法

         invokespecial:调用实例构造器方法、私有方法和父类方法

         invokevirtual:调用所有的虚方法

         invokeinterface:调用接口方法,运行时确定实现此接口的对象

 

解析调用:静态过程,编译期确定,类加载的解析阶段将涉及的符号引用转为确定的直接引用

分派调用:可静可动、根据分派依据的宗量数(宗量:方法调用者和参数)分为单多分派

Human man = new Man();

Human称为变量的静态类型,Man变量的实际类型,这两种类型在程序中均可发送变化

       静态类型的变仅仅在使用时发生,变量本身的静态类型不会被改变

       静态类型编译期可知,实际类型的变化结果在运行期才确定

class Human{  
}    
class Man extends Human{  
}  
class Woman extends Human{  
}  

public class StaticPai{  

    public void say(Human hum){  
        System.out.println("I am human");  
    }  
    public void say(Man hum){  
        System.out.println("I am man");  
    }  
    public void say(Woman hum){  
        System.out.println("I am woman");  
    }  

    public static void main(String[] args){  
        Human man = new Man();  
        Human woman = new Woman();  
        StaticPai sp = new StaticPai();  
        sp.say(man);  
        sp.say(woman);  
    }  
} 

    调say时,方法调用者都为sp的前提下,使用哪个重载版本,取决于传入参数的数量和数据类型,代码刻意定义了两个静态类型相同、实际类型不同的变量,编译器在重载时是通过参数的静态类型作为判定依据决定使用哪个重载版本:静态分派典型应用

 

动态分派:

       方法重写关系紧密,向上转型后调用子类覆写的方法很好的例子,根据对父类实例化的子类不同、调用的是不同子类中覆写的方法:根据变量实际类型来分派方法的执行版本,实际类型在程序运行时才确定

class Eat{  
}  
class Drink{  
}  

class Father{  
    public void doSomething(Eat arg){  
        System.out.println("爸爸在吃饭");  
    }  
    public void doSomething(Drink arg){  
        System.out.println("爸爸在喝水");  
    }  
}  

class Child extends Father{  
    public void doSomething(Eat arg){  
        System.out.println("儿子在吃饭");  
    }  
    public void doSomething(Drink arg){  
        System.out.println("儿子在喝水");  
    }  
}  

public class SingleDoublePai{  
    public static void main(String[] args){  
        Father father = new Father();  
        Father child = new Child();  
        father.doSomething(new Eat());  
        child.doSomething(new Drink());  
    }  
}  

 

编译阶段编译器的选择:静态分派过程(很多情况下这个重载的版本并不唯一,更合适

       选择目标方法的依据:方法的调用者的静态类型是Father还是Child,二方法参数类型是Eat还是Drink:宗量

 

运行阶段虚拟机的选择:动态分派过程

       编译期已确定了目标方法的参数类型(编译期据参数的静态类型进行静态分派),唯一可影响到虚拟机选择的因素只有调用者的实际类型是Father还是Child,一个宗量:单分派类型

 

原文:多态性实现机制——静态分派与动态分派

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值