java静态分派和动态分派
来源:互联网 发布:银行数据统计 编辑:程序博客网 时间:2024/05/15 05:28
本文以Java多态的一些基本特征来谈一下分派调用。
在开始,依旧用常用方式,例子来引入,看一看下面例子的输出:
01
/**
02
*
03
* @author Sel
04
*
05
* 2014.4.3
06
*/
07
public
class
StaticDispatch {
08
09
10
public
void
sayHello(Human guy) {
11
System.out.println(
"hello, guy!"
);
12
}
13
14
public
void
sayHello(Man guy) {
15
System.out.println(
"hello, man!"
);
16
}
17
18
public
void
sayHello(Women guy) {
19
System.out.println(
"hello, women!"
);
20
}
21
22
public
static
void
main(String[] args) {
23
24
Human man =
new
Man();
25
26
Human women =
new
Women();
27
28
StaticDispatch sd =
new
StaticDispatch();
29
30
sd.sayHello(man);
31
32
sd.sayHello(women);
33
34
}
35
36
}
37
38
class
Human {
39
40
}
41
42
class
Man
extends
Human {
43
44
}
45
46
class
Women
extends
Human {
47
48
}
hello, guy!
hello, guy!
没错,程序就是大家熟悉的重载(Overload),而且大家也应该能知道输出结果,但是为什么输出结果会是这个呢?
先来谈一下以下代码的定义:
1
Human man =
new
Man();
其中,变量的静态类型和动态类型在程序中都可以发生变化,而区别是变量的静态类型是在编译阶段就可知的,但是动态类型要在运行期才可以确定,编译器在编译的时候并不知道变量的实际类型是什么(个人认为可能也是因为要实现多态,所以才会这样设定)。
现在回到代码中,由于方法的接受者已经确定是StaticDispatch的实例sd了,所以最终调用的是哪个重载版本也就取决于传入参数的类型了。
实际上,虚拟机(应该说是编译器)在重载时时通过参数的静态类型来当判定依据的,而且静态类型在编译期就可知,所以编译器在编译阶段就可根据静态类型来判定究竟使用哪个重载版本。于是对于例子中的两个方法的调用都是以Human为参数的版本。
Java中,所有以静态类型来定位方法执行版本的分派动作,都称为静态分派。
再来看动态分派,它和多态的另外一个重要体现有很大的关联,这个体现是什么,可能大家也能猜出,没错,就是重写(override)。
例子如下:
01
/**
02
*
03
* @author Sel
04
*
05
* 2014.4.3
06
*/
07
public
class
DynamicDispatch {
08
09
public
static
void
main(String[] args) {
10
11
Human man =
new
Man();
12
Human women =
new
Women();
13
14
man.sayHello();
15
women.sayHello();
16
17
man =
new
Women();
18
man.sayHello();
19
20
}
21
22
}
23
24
abstract
class
Human {
25
protected
abstract
void
sayHello();
26
}
27
28
class
Man
extends
Human {
29
30
@Override
31
protected
void
sayHello() {
32
System.out.println(
"hello man!"
);
33
}
34
35
}
36
37
class
Women
extends
Human {
38
39
@Override
40
protected
void
sayHello() {
41
System.out.println(
"hello women!"
);
42
}
43
44
}
hello man!
hello women!
hello women!
其实由两次改变man变量的实际类型导致调用函数版本不同,我们就可以知道,虚拟机是根据变量的实际类型来调用重写方法的。
我们也可以从例子中看出,变量的实际类型是在运行期确定的,重写方法的调用也是根据实际类型来调用的。
我们把这种在运行期根据实际类型来确定方法执行版本的分派动作,称为动态分派。
- java静态分派和动态分派
- Java的静态分派和动态分派
- JAVA的静态分派和动态分派
- 静态分派和动态分派
- 静态分派和动态分派
- 静态分派和动态分派
- 怎样理解Java静态分派和动态分派
- Java中的静态多分派和动态多分派
- Java中的静态分派与动态分派
- java中的静态分派与动态分派
- Java静态分派与动态分派
- java--动态单分派,静态多分派
- JAVA 静态分派 与动态分派
- Java 静态分派与动态分派
- 学习笔记:动态分派和静态分派
- 【JVM】静态分派和动态分派
- 静态分派与动态分派
- 静态分派与动态分派
- Trie树简介_其中的代码不够好还可以优化
- NYOJ 625 笨蛋的难题(二)
- UVALive 6533
- StringBuffer类的总结
- 网络学习[1]--字节序(大小端)理解
- java静态分派和动态分派
- bulk collect批量定期插入删除行(续)
- OpenCv学习笔记(一)——数字图形的基础和结构
- 电器保护线路的机理
- 函数指针
- 初识数据库之红皮书——实例小结
- read命令
- Java高级视频_IO输入与输出(三)
- 堆和栈的区别