多态是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中的静态分派和动态分派的更多相关文章

  1. java中的静态代理和动态代理,入门整理

    静态代理和动态代理主要解决的问题是:在直接访问对象时带来的问题,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后 ...

  2. java中的静态代理和动态代理

    1.动态代理的定义:为其他对象提供一个代理以控制对这个对象的访问 代理类主要负责委托类的预处理消息,过滤消息,把消息传给委托类以及消息事后处理 按照代理类的创建时期,代理类可以分为2种:静态代理类(在 ...

  3. 一篇文章让你搞懂Java中的静态代理和动态代理

    什么是代理模式 代理模式是常用的java设计模式,在Java中我们通常会通过new一个对象再调用其对应的方法来访问我们需要的服务.代理模式则是通过创建代理类(proxy)的方式间接地来访问我们需要的服 ...

  4. java代理:静态代理和动态代理

    一.Java中有一个设计模式是代理模式 代理模式是常用的Java设计模式,特征是代理类与委托类有相同的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类 ...

  5. 简单介绍Java的静态分派和动态分派

    最近复习JVM的知识,对于静态分派和动态分派的理解有点混乱,于是自己尝试写写代码,在分析中巩固知识. 有如下一段代码,请问每一段分别输出什么? package com.khlin.my.test; c ...

  6. 黑马程序员:Java基础总结----静态代理模式&动态代理

    黑马程序员:Java基础总结 静态代理模式&动态代理   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 静态代理模式 public  class  Ts {   ...

  7. (转)轻松学,Java 中的代理模式及动态代理

    背景:讲到反射机制,肯定会想到动态代理. 轻松学,Java 中的代理模式及动态代理 代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强.值得注意的是,代理类和被代理类应该 ...

  8. C++中的静态多态和动态多态

    C++中的静态多态和动态多态 今天的C++已经是个多重泛型编程语言(multiparadigm programming lauguage),一个同时支持过程形式(procedural).面向对象形式( ...

  9. Java 中(静态)变量、(静态)代码块的执行顺序

    Java 中(静态)变量.(静态)代码块的执行顺序 非原创 本文讨论 Java 中(静态)变量.(静态)代码块的执行顺序 首先创建 3 个类 1.Foo 类 public class Foo { pu ...

  10. Java 中的静态嵌套类和非静态嵌套类

    Java 中的静态嵌套类和非静态嵌套类 术语:嵌套类分为两类:静态嵌套类和非静态嵌套类.声明 static 的嵌套类称为静态嵌套类,非静态嵌套类也称为内部类. class OuterClass { p ...

随机推荐

  1. springboot 完整企业项目搭建实记

    昨天搭建ssm框架时突然想到可以搭建springboot来完美解决配置复杂的问题,今天学习了一下springboot的搭建,在此记录一下搭建的过程和踩过的坑 这里给自己定一个该框架搭建完成的目标,如下 ...

  2. php 判断查询结果是否为空

    select count(people) c from people where people='乐乐' 上面这条sql就是原理 php利用代码 <?php $p=$_POST['p']; $c ...

  3. MATLAB中TXT数据文件读取并写入元胞数组的方法与步骤

    一. TXT数据文件读取 Data = load('train.txt');   %简单的文件读取,这时在工作区可以看到导入的大数据变量Data 二.大数据变量Data装入元胞数组中 D = cell ...

  4. LodRunner实现大负载测试的四部曲(配置系统参数、配置LR、修改脚本、设置组策略)

    见 http://www.51testing.com/?uid-97659-action-viewspace-itemid-210924 LoadRunner以下简称(LR)是目前业界最流行的压力测试 ...

  5. 一些 JS页面的 调用方式init()

    //初始化.... var initAccManPage=function() { //初始化... var initChangeBtn = function(){ $("#btnChang ...

  6. Java Tomcat 注册为Windows系统服务

    注册方法: 1. 在DOS命令行模式下,cd到tomcat的bin目录下 cd tomcatpath 根目录加:后回车 进入到tomcat安装目录,cd bin,进入tomcat启动目录 2.在tom ...

  7. Android无线测试之—UiAutomator UiScrollable API介绍四

    获取与设置最大滚动次数常量值 一.获取与设置最大滚动次数常量值相关API 返回值 API 描述 int getMaxSearchSwipes() 获取执行搜索滑动过程中的最大滑动次数,默认最大滚动次数 ...

  8. 使用 awk 过滤文本或文件中的字符串

    当我们在 Unix/Linux 下使用特定的命令从字符串或文件中读取或编辑文本时,我们经常需要过滤输出以得到感兴趣的部分.这时正则表达式就派上用场了. 什么是正则表达式? 正则表达式可以定义为代表若干 ...

  9. poj_3159 最短路

    题目大意 有N个孩子(N<=3000)分糖果.有M个关系(M<=150,000).每个关系形如:A B C 表示第B个学生比第A个学生多分到的糖果数目,不能超过C.求第N个学生最多比第1个 ...

  10. ios 将p12文件转换为pem

    cd 到 文件所在目录 执行以下命令,生成ck.pem文件. openssl pkcs12 -in ck.p12 -out ck.pem -nodes