以下内容来自周志明的《深入理解Java虚拟机》。

前一篇说了静态分派和重载有关,现在的动态分派就和覆盖Override有关了。

先看代码:

public class DynamicDispatch {
static abstract class Human {
protected abstract void sayHello();
} static class Man extends Human {
@Override
protected void sayHello() {
System.out.println("man");
}
} static class WoMan extends Human {
@Override
protected void sayHello() {
System.out.println("woman");
}
} public static void main(String[] args) {
Human man = new Man();
Human woman = new WoMan();
man.sayHello();
woman.sayHello();
man = new WoMan();
man.sayHello();
}
}

结果输出:

man
woman
woman

这里不再根据静态类型来决定,因为静态类型同样都是Human的两个变量man和woman在调用sayHello()方法时执行了不同的行为,因为这两个变量的实际类型不同。

运行期根据实际类型其确定方法执行版本的分派过程称为动态分派。

原书中作者使用了javap命令输出了这段代码的字节码来分析为何是运行时的不同,还讲解了invokevirtual指令的解析步骤,这里就不赘述了。

单分派和多分派

public class Dispatch {
static class QQ {
} static class _360 {
} public static class Father {
public void hardChoice(QQ args) {
System.out.println("father choose qq");
} public void hardChoice(_360 args) {
System.out.println("father choose 360");
}
} public static class Son extends Father {
public void hardChoice(QQ args) {
System.out.println("son choose qq");
} public void hardChoice(_360 args) {
System.out.println("son choose 360");
}
} public static void main(String[] args) {
Father father = new Father();
Father son = new Son();
father.hardChoice(new _360());
son.hardChoice(new QQ());
}
}
//输出
father choose 360
son choose qq

java语言的静态分派属于多分派类型,在编译阶段,选择目标方法的依据有两点:

1. 静态类型是Father还是Son

2. 方法参数是QQ还是360

动态分派属于单分派类型,在运行时,执行son.hardChoice(new QQ())这句代码时,由于编译器已经决定目标方法的签名必须为harChoice(QQ),虚拟机不会关系传递过来的参数QQ到底是“腾讯QQ”还是"奇瑞QQ",因为这时参数的静态类型和实际类型都对方法的选择不会构成影响,唯一可以影响虚拟机选择的因为只有方法的接受者的类型是Father还是Son。

再重申一下:静态分派在编译器就完成了,动态分派是运行时才进行的。所以Father son=new Son()这句,虽然静态类型是Father,但是运行后的实际类型是Son,所以son.hardChoice执行的是Son类里的方法而不是Father类里的。

[读书笔记]Java之动态分派的更多相关文章

  1. [读书笔记]Java之静态分派

    以下内容来自周志明的<深入理解Java虚拟机>. 静态分派和重载有关. 先看代码: public static void main(String[] args) { SuperClass ...

  2. 《深入了解java虚拟机》高效并发读书笔记——Java内存模型,线程,线程安全 与锁优化

    <深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考& ...

  3. [读书笔记]java核心技术

    ps:有时间好好整理下格式.从别的编辑器拷贝过来啥都没了. ~~~~~~~~~~~~~~· 2.java程序设计环境 JDK 开发java使用的软件: JRE 运行java使用的软件: SE 用于桌面 ...

  4. 深入理解java虚拟机读书笔记--java内存区域和管理

    第二章:Java内存区域和内存溢出异常 2.2运行时数据区域 运行时数据区分为方法区,堆,虚拟机栈,本地方法栈,程序计数器 方法区和堆是线程共享的区域 虚拟机栈,本地方法栈,程序计数器是数据隔离的数据 ...

  5. 读书笔记-Java设计模式

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! Java的封装性很好,拿访问控制符来讲,没有权限的类或方法是不能访问的.如public,都可访问:p ...

  6. [读书笔记]Java类载入过程

    一. 类的生命周期 类从被载入到虚拟机内存中開始,到卸载出内存为止,有下面(如图)的生命周期: 以上"载入->验证->准备->解析->初始化"称为类的载入过 ...

  7. 深入理解Java虚拟机读书笔记 -- Java内存区域

    Graal VM: Run Programs Faster Anywhere. 跨语言全栈虚拟机,可以作为"任何语言"的运行平台使用. Java内存结构 程序计数器:线程私有,较小 ...

  8. [读书笔记]java中的volatile关键词

    以下内容大多来自周志明的<深入理解Java虚拟机>. 当一个变量被volatile修饰后,它将具备两种特性: 1. 保证此变量对所有线程的可见性,这里的“可见性”是指当一条线程修改了这个变 ...

  9. [读书笔记]java中的类加载器

    以下内容大多来自周志明的<深入理解Java虚拟机>. 类加载器是java的一项创新,也是java流行的重要原因之一,它最初是为了满足java applet的需求而开发出来. 什么是appl ...

随机推荐

  1. ros语音交互(四)移植科大讯飞语音识别到ros

    将以前下载的的语音包的 samples/iat_record/的iat_record.c speech_recognizer.c speech_recognizer.c 拷贝到工程src中, linu ...

  2. 更新证书错误:No matching provisioning profiles found

    在Xcode中当你在更新了你得证书而再重新编译你的程序,真机调试会出现“Your build settings specify a provisioning profile with the UUID ...

  3. string类实现(C++)

    class CMyString { friend std::ostream& operator<<( std::ostream& os, const CMyString&a ...

  4. 5.String

    一.古罗马皇帝凯撒在打仗时曾经使用过一种方法加密军事情报.请编写一个程序,使用上述算法加密或解密用户输入的英文字串. 设计思想:先提示用户进行的操作是加密还是解密,用户输入一个字符串,加密时将前23个 ...

  5. hihoCoder#1014

    刚开始学习C语言,准备在做hiho的题目的过程中来学习,在此进行记录,如果代码中有错误或者不当的地方还请指正. 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小 ...

  6. javaIO系统----再看装饰者模式

    javaIO系统拥有各种各样的类,尤其是每次要进行读写操作时,总会一层套一层的new,以前不明白为什么要这样做,不过学习了适配器模式后,对于这种做法立刻了解了:动态扩展IO的功能,使之符合使用者的习惯 ...

  7. 【转】Linux下如何清除系统日志

    使用过Windows的人都知道,在使用windows系统的过程中系统会变得越来越慢.而对于Windows下饱受诟病的各种垃圾文件都需要自己想办法删除,不然系统将会变得越来越大,越来越迟钝!window ...

  8. scala学习----柯里化

    1.鸭子类型,走起来像鸭子,叫起来像鸭子,就是鸭子.函数中使用{ def close(): Unit }作为参数类型,因此任何含有此函数的类都可以作为参数传递.好处是不必使用继承特性. def wit ...

  9. JavaWeb--Servlet部分笔记

    1.集群:数万个服务器协同工作 2.web应用核心组件:jsp和servlet(属于门户),都在web容器中执行 3.web客户端发http请求(大的字符串)给web服务器:web服务器根据头信息来定 ...

  10. Python学习路程day19

    Python之路,Day19 - Django 进阶   本节内容 自定义template tags 中间件 CRSF 权限管理 分页 Django分页 https://docs.djangoproj ...