网站首页 > java教程 正文
背景
考大家一道题目,下面的类执行结果是什么???
public class DispatcherClient {
public static void main(String[] args) {
Animal a = new Animal();
Animal a1 = new Dog();
Animal a2 = new Cat();
Execute exe = new Execute();
exe.execute(a);
exe.execute(a1);
exe.execute(a2);
}
}
class Animal {
}
class Dog extends Animal {
}
class Cat extends Animal {
}
class Execute {
public void execute(Animal a) {
System.out.println("Animal");
}
public void execute(Dog d) {
System.out.println("dog");
}
public void execute(Cat c) {
System.out.println("cat");
}
}
复制代码
不知道大家心里的答案是什么?反正我的答案是错的。
正确的答案是:
为什么是Animal Animal Animal? 而不是Animal dog cat。
类重载本质——静态分派
execute方法是一个重载方法,本质上就是虚拟机JVM如何确定调用哪个方法执行。在java编译后的class文件中存储的只是方法的符号引用,而不是方法在实际运行过程中内存布局的入口地址(直接引用)。而这个方法从符号引用变成直接引用有两种方式,解析和分派。
解析是发生在类加载的解析阶段就会将一部分方法的符号引用转换为直接引用,比如类的静态方法、私有方法、构造方法、父类方法以及final的方法。我们这里不展开阐述,和本例无关。
而我们方法重载的情况下,java采用的是静态分派的方式确定调用方法。
变量类型
在了解静态分派前我们需要了解下变量的类型。
Animal a1 = new Dog();
复制代码
- 静态类型, 也叫做"外观类型", 比如代码中的"Animal", 它的类型是在编译期就知道。
- 实际类型,也叫"运行时类型", 比如代码中的"Dog", 它是在类运行时才会确定,编译期是不知道的。
Execute exe = new Execute();
exe.execute(a);
exe.execute(a1);
exe.execute(a2);
复制代码
这里多次调用了execute方法,在方法接收者已经确定是对象exe的前提下,使用哪个重载的方法,就完全取决于传入参数的数量和数据类型。虚拟机在重载时是通过参数的静态类型而不是实际类型作为判断依据的。因为静态类型是编译期可知的,所以,在编译阶段,编译器会根据静态类型决定使用哪个重载版本,如下图例子中的字节码,技术在编译的字节码中确定了它调用的重载方法。
总结
总结下,所有依赖静态类型来定位方法执行版本的分派叫做静态分派。静态分派的典型应用就是方法重载,它是在编译阶段确定的,它会选择一个最合适的版本方法进行调用。
猜你喜欢
- 2024-11-01 Java | 深入理解方法调用的本质(含重载与重写区别)
- 2024-11-01 Java中的方法重载和方法重写的区别
- 2024-11-01 经典回答:《重载和重写的区别》Java面试冲击月薪40K高薪
- 2024-11-01 java 核心技术-12版 卷Ⅰ- 4.6 对象构造 4.6.1重载
- 2024-11-01 Java语言基础图解-第二阶段(继承-重载-重写-多态-抽象-接口)
- 2024-11-01 阿瑟Java (17):重载、重写有区别吗?
- 2024-11-01 Java基础——构造器重载 & this关键字
- 2024-11-01 「Java面试题」常规Java面试题分享
- 2024-11-01 Java每日一题之重载和重写有什么区别?
- 2024-11-01 Java里方法重写override与方法重载overload有什么区别?
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)