浅谈动态分派和静态分派

前言

动态分派和静态分派机制是Java多态实现的原理。本文将针对这两种机制进行浅析。

静态分派

静态分派机制最典型的代码示例如下

    void test() {
        Father father = new Son();          //静态分派
        print(father);
    }

    void print(Father father) {
        System.out.println("this is father");
    }

    void print(Son son) {
        System.out.println("this is son");
    }

这段代码执行完成以后会输出this is father。之所以会输出这样一个结果,原因就是此处的多态实现是静态分派的。在编译阶段,由于father变量类型被声明为Father。因此在编译阶段就已经确定了调用的是参数为Father的方法,与具体的实例化对象无关

动态分派

动态分派机制最典型的代码示例如下

    void test() {
        Father father = new Son();          //静态分派
        father.name();      //动态分派
    }

    class Son extends Father {
        void name(){
            System.out.println("son");
        }
    }

    class Father {
        void name(){
            System.out.println("father");
        }
    }

这里我们声明了静态类型Father,但是实际上我们调用name方法的时候,输出的却是son。这里就牵扯到一个动态分派的问题,对于方法重写,Java采用的是动态分派机制,也就是说在运行的时候才确定调用哪个方法。由于father的实际类型是Son,因此调用的就是Son的name方法。

单分派与多分派

静态分派是多分派的,动态分派是单分派的。

多分派是指在静态分派的过程中需要考虑两步:

1、判断静态类型是Father还是Son

2、判断方法参数是Father还是Son

综合上述两个因素(宗量),才能确定调用哪个方法。

而动态分派由于使用的时候已经确定了参数类型,所以不需要对参数类型进行判断,只需要对变量类型进行判断即可。比如在上述例子中,我们已经通过静态分派,确定了调用的是无参的name方法,这时候我们就只需要考虑father的实际类型是Father还是Son即可。因此动态分派是单分派的。

总结

在Java多态的两种常见用法中,方法重载使用的是静态分派机制,而方法重写使用的是静态分派机制。这也就导致了,方法重载调用的时候是根据变量的静态类型来决定调用哪个方法。而方法重写的时候,则是根据变量的实际类型来决定调用哪个方法。

原文地址:https://www.cnblogs.com/zhenlingcn/p/8539065.html

时间: 2024-08-29 12:16:04

浅谈动态分派和静态分派的相关文章

从内存层次浅谈动态与静态

转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5827364.html 静态内容:在内存中有一片特定的区域,不属于某特定的类对象,而是属于所有类对象,每个对象默认有指针指向这片区域,以调用静态的属性.方法 当创建第一个类对象时,类代码由硬盘加载到内存时,静态内容加载一次,开辟区域存放,之后每次创建对象时不再加载.每个对象默认有指针指向这片区域,以调用静态的属性.方法. 所以,静态方法的调用格式为:  类名.静态方法名 .  对象名.方法名  均可 动态内容

浅谈动态数组原理及其实现

stl中的vector是竞赛中常用的容器,原因在于省内存,O(1)在后端插入和删除.随机下标访问,今天就来谈谈它的实现. 最简单的一个动态数组 动态数组并不是真正意义上的动态的内存,而是一块连续的内存,当添加新的元素时,容量已经等于当前的大小的时候(存不下了),执行下面3步 重新开辟一块大小为当前容量两倍的数组 把原数据拷贝过去 释放掉旧的数组 完事后再把这个元素加在后面. 那么你一定会很好奇,它为什么会是O(1).这个是均摊下来的结果,我们只需要证明总共拷贝的元素个数是O(n)级别的就好了(因

浅谈-Java设计模式之静态代理

代理模式(Proxy pattern):当一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用.静态代理是具体去实现需要代理对象接口,覆写方法时进行个性化操作. 单独为代理而实现作为某个接口实现类的则为静态代理(Static Proxy). 不多说了,上代码? package com.ant; public interface Hello { public void say(); } package com.ant; public class HelloIm

浅谈动态人脸识别技术原理

人脸辨认,是依据人的脸部特征信息进行身份辨认的一种生物辨认技能.用摄像机或摄像头收集含有人脸的图画或视频流,并主动在图画中检测和跟踪人脸,进而对检测到的人脸进行脸部的一系列相关技能,一般也叫做人像辨认.面部辨认. 人脸辨认体系的研讨始于20世纪60年代,80年代后跟着计算机技能和光学成像技能的开展得到提高,而真实进入初级的运用阶段则在90年后期,并且以美国.德国和日本的技能完成为主:人脸辨认体系成功的关键在于是否具有顶级的中心算法,并使辨认成果具有实用化的辨认率和辨认速度:"人脸辨认体系&quo

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

方法解析 Class 文件的编译过程中不包含传统编译中的连接步骤,一切方法调用在 Class 文件里面存储的都只是符号引用,而不是方法在实际运行时内存布局中的入口地址.这个特性给 Java 带来了更强大的动态扩展能力,使得可以在类运行期间才能确定某些目标方法的直接引用,称为动态连接,也有一部分方法的符号引用在类加载阶段或第一次使用时转化为直接引用,这种转化称为静态解析.这在前面的“Java 内存区域与内存溢出”一文中有提到. 静态解析成立的前提是:方法在程序真正执行前就有一个可确定的调用版本,并

Java静态分派与动态分派(二)

方法调用并不等于方法执行,方法调用阶段唯一的任务就是确定被调用方法的版本(即调用哪一个方法),暂时还不涉及方法内部的具体运行过程. 在程序运行时,进行方法调用是最普遍.最频繁的操作,但是Class文件的编译过程不包括传统编译中的连接步骤,一切方法调用在Class文件里面存储的都只是符号引用,而不是方法在实际运行时内存布局中的入口地址(相对于之前说的直接引用).这个特性给Java带来了更强大的动态扩展能力,但也使得Java方法调用过程变得相对复杂起来,需要在类加载期间,甚至到运行期间才能确定目标方

(三十)分派调用:静态分派和动态分派

分派调用 其实分派分为两种,即动态分派和静态分派.我们在了解分派的时候,通常把它们与重写和重载结合到一起. 重载(overload)与静态分派 我们先看一个题: public class Main { static abstract class Father { } static class Son extends Father { } static class Daughter extends Father { } public void getSex(Daughter daughter) {

Java静态分派和动态分派

前言 动态分派和静态分派机制是Java多态实现的原理.本文将针对这两种机制进行浅析. 静态分派 静态分派机制最典型的代码示例如下 void test() { Father father = new Son(); //静态分派 print(father); } void print(Father father) { System.out.println("this is father"); } void print(Son son) { System.out.println("

JVM 方法调用之静态分派

分派(Dispatch)可能是静态也可能是动态的,根据分派依据的宗量数可分为单分派和多分派.这两种分派方式的两两组合就构成了静态单分派,静态多分派,动态单分派,动态多分派这4种组合.本章讲静态分派. 1.静态分派 所有依赖静态类型来定位方法执行版本的分派动作称为静态分派.静态分派的典型应用是方法重载.静态分派发生在编译阶段,因此确定静态分派的动作实际上不是由虚拟机来执行的. 那么什么是静态类型(static type)呢? 1 Super object = new Sub(); 像上面的语句,S