java中的静态分派和动态分派
多态是java的基本特征之一,多态即一个对象具有多种形态(多种表达形式,猴子是动物的一种的表现形式),例如:子类是父类的一种形态。
当方法重载时,就会涉及到多态。
1:在重载时是通过参数的静态类型,而不是实际类型确定的, 静态类型是编译期确定的。
例如:
package com.li.chapter08; /**
* 静态分派
*/
public class StaticDispatch {
static abstract class Human{
} static class Women extends Human{
} static class man extends Human{
}
public void sayHello(Human human) {
System.out.println("hello,human");
} public void sayHello(Women women) {
System.out.println("hello, women");
} public void sayHello(man man) {
System.out.println("hello, man");
} public static void main(String[] args){
man man=new man(); //man是Human的一种形态,
Human women=new Women(); //Human是静态类型,Women是实际类型 StaticDispatch staticDispatch=new StaticDispatch();
staticDispatch.sayHello(man); //编译期确定参数的类型,使用 human的静态类型Human
staticDispatch.sayHello(women); /**
* 结果
* hello,man
hello,human
*/
}
}
其中:Human 被称为静态类型,man,Women被称为实际类型。在编译期,参数就确定了,使用对象的静态类型。
2:当重载方法时,参数可能有很多版本,也就是参数对象具有层次结构。具体选择哪一种重置方法要看静态类型的匹配优先级
例如;
package com.li.chapter08; import org.junit.Test; /**
* @program: GradleTestUseSubModule
* @author: Yafei Li
* @create: 2018-07-07 08:29
* 自定义方法重载,选择合适的重载方法
* 静态分派(Static Dispatch)发生在编译时期,分派根据静态类型(父类型)信息发生。静态分派对于我们来说并不陌生,方法重载就是静态分派。
* 动态单分派在Java语言中是在子类重写父类的方法时发生的
**/
public class MyStaticDispatcher { class OneGeneration{
}
class TwoGeneration extends OneGeneration{ }
class ThreeGeneration extends TwoGeneration{ }
class FourGeneration extends ThreeGeneration{ } public void test(TwoGeneration twoGeneration) {
System.out.println("twoGenration");
} public void test(ThreeGeneration threeGeneration) {
System.out.println("threeGeneration");
} @Test
public void main(){
MyStaticDispatcher myStaticDispatcher=new MyStaticDispatcher();
FourGeneration fourGeneration=new FourGeneration();
myStaticDispatcher.test(fourGeneration); //打印:threeGeneration }
}
当传入参数的对象,确定使用哪一种重载的方法时,需要根据参数对象在继承结构中从低到高遍历,选择第一个匹配的重载方法。
3:动态分派
动态分派是多态性的另一个重要体现——(重写)override
package com.li.chapter08; import org.apache.tools.ant.taskdefs.Java; import java.lang.invoke.MethodType; /**
* 动态分派
*/
public class DynamicDispatch {
static abstract class Human{
protected abstract void sayHello();
}
static class Man extends Human{ @Override //重写
protected void sayHello() {
System.out.println("man say hello");
}
}
static class Woman extends Human{ @Override //重写,覆盖
protected void sayHello() {
System.out.println("Woman say hello");
}
} public static void main(String[] args){
Human man=new Man();
Human woman=new Woman(); man.sayHello();
woman.sayHello(); man=new Woman();
man.sayHello();
/**
* man say hello
Woman say hello
Woman say hello
*/
}
}
使用 invokevirtual指令进行多态性的查找时,使用以下几个步骤:
1)找到操作数栈顶的第一个元素所指向的对象的实际类型,记作C。
2)如果在类型C中找到与常量中的描述符和简单名称都相符的方法,则进行访问权限校验,如果通过则返回这个方法的直接引用,查找过程结束;如果不通过,则返回java.lang.IllegalAccessError异常。
3)否则,按照继承关系从下往上依次对C的各个父类进行第2步的搜索和验证过程。
4)如果始终没有找到合适的方法,则抛出java.lang.AbstractMethodError异常。
我们把这种在运行期根据实际类型确定方法执行版本的分派过程称为动态分派。
4:单分派与多分派
方法的接受者(所有者)与方法的参数统称为方法的宗量,根据分配基于多少宗量,可以划分为单分派和多分派两种。
单分派是根据一个宗量对目标方法进行选择,多分派则是根据多于一个宗量对目标方法进行选择。
java语言是动态单分派(只根据方法的接收者的实际类型确定),静态多分派(根据编译期静态类型和参数类型确定)语言。
5:访问者模式中用的动态多分派。
http://www.cnblogs.com/java-my-life/archive/2012/06/14/2545381.html
java中的静态分派和动态分派的更多相关文章
- java中的静态代理和动态代理,入门整理
静态代理和动态代理主要解决的问题是:在直接访问对象时带来的问题,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后 ...
- java中的静态代理和动态代理
1.动态代理的定义:为其他对象提供一个代理以控制对这个对象的访问 代理类主要负责委托类的预处理消息,过滤消息,把消息传给委托类以及消息事后处理 按照代理类的创建时期,代理类可以分为2种:静态代理类(在 ...
- 一篇文章让你搞懂Java中的静态代理和动态代理
什么是代理模式 代理模式是常用的java设计模式,在Java中我们通常会通过new一个对象再调用其对应的方法来访问我们需要的服务.代理模式则是通过创建代理类(proxy)的方式间接地来访问我们需要的服 ...
- java代理:静态代理和动态代理
一.Java中有一个设计模式是代理模式 代理模式是常用的Java设计模式,特征是代理类与委托类有相同的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类 ...
- 简单介绍Java的静态分派和动态分派
最近复习JVM的知识,对于静态分派和动态分派的理解有点混乱,于是自己尝试写写代码,在分析中巩固知识. 有如下一段代码,请问每一段分别输出什么? package com.khlin.my.test; c ...
- 黑马程序员:Java基础总结----静态代理模式&动态代理
黑马程序员:Java基础总结 静态代理模式&动态代理 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 静态代理模式 public class Ts { ...
- (转)轻松学,Java 中的代理模式及动态代理
背景:讲到反射机制,肯定会想到动态代理. 轻松学,Java 中的代理模式及动态代理 代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强.值得注意的是,代理类和被代理类应该 ...
- C++中的静态多态和动态多态
C++中的静态多态和动态多态 今天的C++已经是个多重泛型编程语言(multiparadigm programming lauguage),一个同时支持过程形式(procedural).面向对象形式( ...
- Java 中(静态)变量、(静态)代码块的执行顺序
Java 中(静态)变量.(静态)代码块的执行顺序 非原创 本文讨论 Java 中(静态)变量.(静态)代码块的执行顺序 首先创建 3 个类 1.Foo 类 public class Foo { pu ...
- Java 中的静态嵌套类和非静态嵌套类
Java 中的静态嵌套类和非静态嵌套类 术语:嵌套类分为两类:静态嵌套类和非静态嵌套类.声明 static 的嵌套类称为静态嵌套类,非静态嵌套类也称为内部类. class OuterClass { p ...
随机推荐
- Redis 响应延迟问题排查
计算延迟时间 如果你正在经历响应延迟问题,你或许能够根据应用程序的具体情况算出它的延迟响应时间,或者你的延迟问题非常明显,宏观看来,一目了然.不管怎样吧,用redis-cli可以算出一台Redis 服 ...
- Centsos7修改密码
CentOS 7.0 进入单用户模式修改Root密码 时间:2017-05-02 01:10来源:blog.csdn.net 作者:海哥_大大的Java 举报 点击:506次 一.启动时,随便按 ...
- JobTracker作业启动过程分析
转自:http://blog.csdn.net/androidlushangderen/article/details/41356521 在Hadoop中,启动作业运行的方式有很多,可以用命令行格式把 ...
- java----代理机制或动态类的生成
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- leetcode:Pascal's Triangle
一. 题目 经典题目,杨辉三角,输入行数.生成杨辉三角的数组. 二. 分析 首先,我们知道有例如以下规律: 1.每一行的第一个数和最后一个数都为1 2.中间的数是上面数和上面数左边的数 ...
- Cocos2d-X中的Slider控件
Slider控件事实上就是滑块控件.经常使用于音乐中的音量控制,在Windows编程中开发音乐播放器就须要用到滑块控件控制音量 首先在project文件夹下的Resource文件夹中放 在Skider ...
- LoadRunner学习---脚本编写(4)(比较重要)
今天接着来翻译http://www.wilsonmar.com/中关于LoadRunner脚本编写部分,下面该翻译脚本编写中一些比较重要的部分了. Web用户Action 在VuGen中,脚本产生的默 ...
- Logstash zabbix 插件
zabbix 监控 logstash 安装社区扩展包wget http://download.elasticsearch.org/logstash/logstash/logstash-contrib- ...
- nib文件的默认搜索规则
if you do not specify a nib name, and do not override the loadView method in your custom subclass, t ...
- poj_2486 动态规划
题目大意 N个节点构成一棵树,每个节点上有一个权重val[i], 从根节点root出发在树上行走,行走的时候只能沿着树枝行进.最多在树上走k步,每第一次到达某个节点j,可以获得val[j]的收益,求从 ...