编译器如何决定是重载还是重写? [英] How does the compiler decide between overloading and overriding?

查看:0
本文介绍了编译器如何决定是重载还是重写?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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中,一旦确认,则在运行时检查对象类型并执行相应的方法,即应该执行类B的doSomething(),而执行类AdoSomething()

如果两个方法相同,则只执行BdoSomething()类。 编译器如何确定某个方法被重写,从而由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)运行。

这篇关于编译器如何决定是重载还是重写?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆