首页 > 编程语言 >Java方法重载的本质

Java方法重载的本质

时间:2022-08-27 13:01:25浏览次数:95  
标签:execute exe Java 静态 本质 Animal 重载 方法

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

上述语句会输出什么呢?

答案是

类重载本质 - 静态分派

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

总结

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

参考

https://juejin.cn/post/7133592301477036063

标签:execute,exe,Java,静态,本质,Animal,重载,方法
From: https://www.cnblogs.com/bmmxz/p/16630378.html

相关文章

  • java 连接 redis
    Jedis导入对应的依赖<dependencies><!--jedis--><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId>......
  • Java10-接口,多态
    第一章接口1.1概述接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么接口的内部主要就是封装了方法,包含抽象方法(JDK7......
  • java自定义stream
    一、流程1//自定义集合,继承ArrayList,与ArrayList没啥区别SelfList<Apple>appleList=newSelfList<>();importjava.util.ArrayList;importjav......
  • Java调用Windows系统命令CMD
    Java的Runtime.getRuntime().exec(commandStr)可以调用执行cmd指令。cmd/cdir是执行完dir命令后关闭命令窗口。 cmd/kdir是执行完dir命令后不关闭命令窗口。 ......
  • win10环境安装vs2015的问题:缺少JavaScript_ProjectSystem.msi和JavaScript_LanguageSe
    最近有同事在win10下安装vs2015总是报错,安装中途报缺少文件JavaScript_ProjectSystem.msi和JavaScript_LanguageService.msi。想想看微软发布的产品应该不至于丢三落四,缺......
  • D11(java基础)
    D11(java基础)流概念:内存与存储设备之间传输数据的通道。流的分类按方向:输入流:将存储设备中的内容读入到内存中。输出流:将内存中的内容写入到存储设备中。......
  • JavaSE-Day02-Java方法
    Java方法什么是方法System.out.println() 类.对象.方法()Java方法是语句的集合,他们在一起执行一个功能方法是解决一类问题的步骤的有序集合方法包含于类或对象之中......
  • 【FAQ】【JAVA UI】HarmonyOS 如何获取uid和pid
    ​ 【问题描述】鸿蒙中怎么样可以获取Uid和Pid 【解决方案】try{BundleInfobundleInfo=getContext().getBundleManager().getBundleInfo(getBund......
  • 肖sir__java__02基本
    注意点:1、java中首字母大小写区分2、类名首个字母大写3、方法名,首字母小写,多个单词后面大写4.文件名和类名一致,后缀名为.java5.出现波浪线就市报错6、都是main方法......
  • java如何实现对List集合进行分页
    对List集合进行分页:private<T>Page<T>listToPage(List<T>dataList,IntegerpageSize,IntegerpageNumber){Page<T>result=newPage<T>();List<T>monit......