多态是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. CImage类提供了GetBits()函数原理及实现

    CImage类提供了GetBits()函数来读取数据区,GetBits()函数返回的是图片最后一行第一个像素的地址,网上有人说返回指针的起始位置是不同的,有些图片返回的是左上角像素的地址,有些是左下角 ...

  2. Qt slot中获取sender

    调用sender();函数 例如获取一个QRadioButton QRadioButton *rb = qobject_cast<QRadioButton *>(sender());

  3. M451定时器的寄存器讲解

    M451的定时器的寄存器的这一章节,相信很多人都清楚明白了,但还是有必要说一说的 /** * @brief Timer0 IRQ * * @param None * * @return None * ...

  4. Mysql 知识点总结

    1.创建数据库    mysqladmin 下面是一个简单的例子,创建名为 yiibai_tutorials1 的数据库. D:\software\mysql--winx64\bin> mysq ...

  5. 160615、Spring3 MVC 拦截器拦截不到的问题

    昨天项目组有个成员使用拦截器的时候发现不起作用,后来发现了原因,在这里跟大家分享一下(主要是冲突了).分享的是一位网友写的文章,他总结的很好. com.zk.interceptors.MyInterc ...

  6. img元素的alt和title的区别?

    alt是图片加载失败时显示在网页上的提示信息: title是鼠标放上面时显示的文字(图片加载失败鼠标放显示的代替文字上时仍然会显示提示信息): 除此之外,alt是img的必要属性,只能用在img.ar ...

  7. synchronized和volatile的使用方法以及区别

    先看看下面的例子: public class ThreadTest { public static void main(String[] args) { final Counter counter = ...

  8. MySQL 监控指标

    为了排查问题,对数据库的监控是必不可少的,在此介绍下 MySQL 中的常用监控指标. 简介 MySQL 有多个分支版本,常见的有 MySQL.Percona.MariaDB,各个版本所对应的监控项也会 ...

  9. echarts将折线图改为曲线图

    只要在 series中加上属性: smooth: true(true为曲线.flase为直线)

  10. 国产服务器离线安装gm

    离线安装过程: 1.安装JPEGlib cd /opt/ ls tar -zxvf jpegsrc.v9b.tar.gz cd jpeg-9b/ ./configure make make insta ...