gpt4 book ai didi

java - 编译器如何决定重载和覆盖?

转载 作者:行者123 更新时间:2023-12-05 01:25:20 24 4
gpt4 key购买 nike

class A {
public void doSomething(float f) {
//print "in A"
}
}

class B extends A {
public void doSomething(int i) {
// print "in B"
}

public static void main(String[] args) {
A a = new B();
a.doSomething(10);
}
}

编译器首先检查是否doSomething()存在于A类中。一旦确认,在运行时,将检查对象类型并执行相应的方法,即doSomething()。应执行 B 类,但 doSomething()A而是执行。

如果两种方法相同,则只有类 B doSomething()将被执行。编译器如何决定某个方法被覆盖,从而由 JVM 处理?

最佳答案

简单来说:

  1. 编译器选择将被调用的方法的签名
  2. 运行时选择将运行编译器选择的签名的哪个实现

在第 1 步中,编译器查看调用方法的对象的声明类型,以及参数类型,这意味着:

  • 编译器只知道aA(“声明类型”,又名静态类型);因此它只能搜索 A 中的方法或 A 继承的方法。这意味着在您的示例中,编译器甚至不会在类 B 中搜索 doSomething
  • 它查看参数的数据类型以解析重载中的一个方法。在您的示例中,这不是必需的,因为只有一种 doSomething 方法(带有 float 参数的方法)

基于以上,编译器只能断定是 doSomething(float) 会运行。您可以将其视为编译器选择的方法签名是一成不变的,运行时无法更改它。

在第 2 步中,运行时知道将运行哪个签名 (doSomething(float)),它唯一需要做的就是选择将调用该签名的哪个实现。为此,它查看示例中的实际对象类型(创建的对象)new B()。然后它将在 B 中运行实现,如果被覆盖,或者在树中搜索该确切签名的任何被覆盖的实现,直到它到达 A 中的继承实现。因为 B 没有覆盖 doSomething(float),所以从 A 继承的实现 A.doSomething(float) 运行.

关于java - 编译器如何决定重载和覆盖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70903355/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com