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 ...
随机推荐
- JavaScript重载
在Javascript 中,每个函数都有一个隐含的对象arguments,表示给函数 实际传给的参数 ,那么我们可以用 arguments来实现函数的重载 <!DOCTYPE html PUBL ...
- 测试RESTful API利器-Postman
对于前端开发者而言,最需要的往往不是技术本身,其实技术都没什么难的,而最缺少的则是各种各样好的兵器,比如调试,开发工具等等. 我们这里就推荐一款前端开发的利器-Postman,它是Google Chr ...
- hdu 1392:Surround the Trees(计算几何,求凸包周长)
Surround the Trees Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- 说说JSON和JSONP 也许你会豁然开朗
说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决 前言 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只 ...
- UE4插件
源代码中包含一些插件例子 C:\Program Files\Epic Games\UE_4.15\Engine\Plugins\Developer 一下截图来自官网https://docs.unrea ...
- Android之ListView中的分割线
ListView中每个Item项之间都有分割线,设置android:footerDividersEnabled表示是否显示分割线,此属性默认为true. 1.不显示分割线只要在ListView控件中添 ...
- Scrapy使用详细记录
这几天,又用到了scrapy框架写爬虫,感觉忘得差不多了,虽然保存了书签,但有些东西,还是多写写才好啊 首先,官方而经典的的开发手册那是需要的: https://doc.scrapy.org/en/l ...
- 理解Javascript__理解undefined和null
来自普遍的回答: 其实在 ECMAScript 的原始类型中,是有Undefined 和 Null 类型的. 这两种类型都分别对应了属于自己的唯一专用值,即undefined 和 null. 值 un ...
- 利用CSS3制作淡入淡出动画效果
CSS3新增动画属性“@-webkit-keyframes”,从字面就可以看出其含义——关键帧,这与Flash中的含义一致. 利用CSS3制作动画效果其原理与Flash一样,我们需要定义关键帧处的状态 ...
- centos7 安装kafka Manager
1.安装sbt编译环境 curl https://bintray.com/sbt/rpm/rpm |tee /etc/yum.repos.d/bintray-sbt-rpm.repo yum inst ...