当前位置: 首页 > 面试题库 >

重载是编译时多态。真?

黄磊
2023-03-14
问题内容

我确实知道重载和重载之间的语法差异。而且我也知道,重载是运行时多态,重载是编译时多态。但是我的问题是:“重载真的是编译时的多态性吗?方法调用真的在编译时解决了吗?”。为了阐明我的观点,让我们考虑一个示例类。

public class Greeter {
    public void greetMe() {
        System.out.println("Hello");
    }

    public void greetMe(String name) {
        System.out.println("Hello " + name);
    }

    public void wishLuck() {
        System.out.println("Good Luck");
    }
}

由于所有方法greetMe(), greetMe(String name), wishLuck()都是公开的,因此可以全部重写(包括重载的方法),对吗?例如,

public class FancyGreeter extends Greeter {
    public void greetMe() {
        System.out.println("***********");
        System.out.println("*  Hello  *");
        System.out.println("***********");
    }
}

现在,考虑以下代码片段:

Greeter greeter = GreeterFactory.getRandomGreeter();
greeter.greetMe();

getRandomGreeter()方法返回一个随机Greeter对象。它可以返回的对象Greeter,或者它的任何子类,例如FancyGreeterGraphicalGreeter或任何其他一个。在getRandomGreeter()将或者使用创建的对象new或动态地加载类文件,并使用反射(我认为这是可能的反射)或这是可能的任何其他方式创建对象Greeter子类中可能会覆盖也可能不会覆盖所有这些方法。因此,编译器无法知道是否重写了特定方法(是否已重载)。对?另外,维基百科在虚函数中说:

在Java中,默认情况下,所有非静态方法都是“虚拟函数”。只有标有关键字final的方法(不能被覆盖)以及私有方法(不能被继承)是非虚拟的。

由于虚拟函数是在运行时使用动态方法分派来解析的,并且由于所有非私有,非最终方法都是虚拟的(无论是否重载),因此必须在运行时解析它们。对?

那么,如何在编译时解决重载呢?或者,是否有我误解的东西,或者我想念什么?


问题答案:

如果您要的话,仍然可以重写重载的方法。

重载的方法就像不同的族,即使它们共享相同的名称。编译器会静态地选择一个具有给定签名的系列,然后在运行时将其分派到类层次结构中最具体的方法。

也就是说,方法分派分两个步骤执行:

  • 第一个是在编译时使用可用的静态信息完成的,编译器将为call签名发出一个与您当前的方法参数最匹配的签名,该重载方法在调用该方法的对象的声明类型中的重载方法列表中。
  • 第二步在运行时执行,给定应该调用的方法签名(上一步,还记得吗?),JVM将把它分派到接收器对象实际类型中最具体的覆盖版本。

如果方法参数类型根本不是协变的,则重载等效于在编译时修改方法名称;因为它们实际上是不同的方法,所以JVM永远不会根据接收者的类型互换分配它们。



 类似资料:
  • null 因为在阅读第一点时,我感觉到为什么特别提到静态方法,而不提到实例方法和构造函数。 谢谢

  • 本文向大家介绍C#中的编译时多态是什么?,包括了C#中的编译时多态是什么?的使用技巧和注意事项,需要的朋友参考一下 多态可以是静态的也可以是动态的。在静态多态性中,对函数的响应是在编译时确定的。在动态多态中,它是在运行时决定的。 在编译期间将函数与对象的链接称为早期绑定。也称为静态绑定。C#提供了两种技术来实现静态多态性。它们是函数重载和运算符重载。 在函数重载中,可以在同一作用域中为相同的函数名

  • 问题内容: 在我提出问题之前,让我解释一下我的理解和看法。 除非进行覆盖,否则仅通过Override才能实现多态。而且,它只能在运行时看到,人们可能将其命名为“运行时多态性”。( 我不反对将 多态 称为 运行时多态 ) 我反对 将 方法重载 称为 编译时多态 或多 态 。 我同意 方法重载 是静态绑定(编译时绑定),但是我看不到其中的多态性。 根据javadoc,只有多态性。没有编译时或运行时多态

  • 但我的问题是,如果它不使用AspectJ进行编织,那么Spring AOP是否有自己的编织,它是在加载时还是编译时执行? 我的Spring配置XML文件的相关部分是:

  • 本文向大家介绍编译时多态和运行时多态之间的区别,包括了编译时多态和运行时多态之间的区别的使用技巧和注意事项,需要的朋友参考一下 多态性是最重要的OOP概念之一。它是一个概念,通过它我们可以以多种方式执行单个任务。多态有两种类型,一种是编译时多态,另一种是运行时多态。 方法重载是编译时多态的示例,方法重载是运行时多态的示例。 序号 键 编译时多态 运行时多态 1个 基本的 R un time多态性,