携手创造,共同成长!这是我参与「日新方案 8 月更文挑战」的第22天,点击检查活动概况

布景

考咱们一道标题,下面的类履行结果是什么???

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

不知道咱们心里的答案是什么?横竖我的答案是错的。

正确的答案是:

Java方法重载的本质

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

Java方法重载的本质

总结

总结下,一切依赖静态类型来定位办法履行版别的分配叫做静态分配。静态分配的典型使用就是办法重载,它是在编译阶段确认的,它会挑选一个最合适的版别办法进行调用。

\

参阅

/post/684490…