Java方法重载的本质

简介: 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");
    }
}

不知道大家心里的答案是什么?反正我的答案是错的。

正确的答案是:

1671174105589.jpg

为什么是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的前提下,使用哪个重载的方法,就完全取决于传入参数的数量和数据类型。虚拟机在重载时是通过参数的静态类型而不是实际类型作为判断依据的。因为静态类型是编译期可知的,所以,在编译阶段,编译器会根据静态类型决定使用哪个重载版本,如下图例子中的字节码,技术在编译的字节码中确定了它调用的重载方法。

1671174121504.jpg


总结


总结下,所有依赖静态类型来定位方法执行版本的分派叫做静态分派。静态分派的典型应用就是方法重载,它是在编译阶段确定的,它会选择一个最合适的版本方法进行调用。

目录
相关文章
|
2月前
|
存储 Java
Java基础手册(标识符 关键字 字面值 变量 数据类型 字符编码 运算符 控制语句 方法及方法重载和递归 面向对象与面向过程)
Java基础手册(标识符 关键字 字面值 变量 数据类型 字符编码 运算符 控制语句 方法及方法重载和递归 面向对象与面向过程)
28 0
|
3月前
|
安全 Java 编译器
深入理解Java语言中的方法重载(Overloading)
深入理解Java语言中的方法重载(Overloading)
|
3月前
|
Java 编译器
滚雪球学Java(36):玩转Java方法重载和可变参数,让你的代码更灵活
【5月更文挑战第11天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
27 0
滚雪球学Java(36):玩转Java方法重载和可变参数,让你的代码更灵活
|
3月前
|
Java 编译器
Java构造方法重载的深入探索
Java构造方法重载的深入探索
23 0
|
3月前
|
Java
java面试基础 -- 方法重载 & 方法重写
java面试基础 -- 方法重载 & 方法重写
21 0
|
3月前
|
自然语言处理 Java 编译器
【Java探索之旅】方法重载 递归
【Java探索之旅】方法重载 递归
22 0
|
3月前
|
Java 编译器
每日一道Java面试题:方法重载与方法重写,这把指定让你明明白白!
每日一道Java面试题:方法重载与方法重写,这把指定让你明明白白!
34 0
|
3月前
|
Java
Java方法继承、方法重载、方法覆盖总结
总之,继承实现类的层次结构,方法重载提供方法的多样性,方法覆盖实现多态性。这些概念是面向对象编程的核心,用于实现代码的结构、灵活性和可维护性。 买CN2云服务器,免备案服务器,高防服务器,就选蓝易云。百度搜索:蓝易云
18 0
|
3月前
|
自然语言处理 Java 编译器
【详识JAVA语言】方法重载
【详识JAVA语言】方法重载
32 1
|
3月前
|
Java
深入理解 Java 方法重载与递归应用
方法重载 允许在同一个类中定义多个具有相同名称的方法,但 参数列表 必须不同。
49 0