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

Java方法重载+双调度

贺雪松
2023-03-14
问题内容

谁能详细解释在我的测试代码段中print(Parent parent)使用Child实例时重载方法被调用的原因?

这里涉及虚拟方法或Java中方法重载/解析的特殊性吗?是否直接引用Java Lang Spec?哪个术语描述了这种行为?非常感谢。

public class InheritancePlay {

    public static class Parent {        
        public void doJob(Worker worker) {
            System.out.println("this is " + this.getClass().getName());

            worker.print(this);
        }
    }

    public static class Child extends Parent {
    }

    public static class Worker {
        public void print(Parent parent) {
            System.out.println("Why this method resolution happens?");
        }

        public void print(Child child) {
            System.out.println("This is not called");
        }
    }

    public static void main(String[] args) {
        Child child = new Child();
        Worker worker = new Worker();

        child.doJob(worker);
    }
}

问题答案:

JLS在§8.4.9重载中规定:

  1. 调用方法时(第15.12节),实际参数(和任何显式类型参数)的数量以及参数的 编译时类型 在编译时用于确定将要调用的方法的签名( §15.12.2)。
  2. 如果要调用的方法是实例方法,则将在运行时使用动态方法查找(第15.12.4节)确定要调用的实际方法。

因此,在您的情况下:

  1. 方法参数(this)为编译时类型Parent,因此将print(Parent)调用该方法。
  2. 如果Worker该类是子类的,并且该子类将重写该方法,而该worker实例是该子类的实例,则将调用重写的方法。

Java中不存在双调度。您必须模拟它,例如,使用“
访客模式”。在这种模式下,基本上,每个子类都实现一个accept方法并以this作为参数调用visitor
,并this具有该子类的编译时类型,因此使用了所需的方法重载。



 类似资料:
  • 问题内容: 对于以下代码,为什么打印A,B?我希望它能打印B,B。而且,由JVM执行的方法调用是动态还是静态评估? 问题答案: 重载由编译器 静态 确定。 重写 是在执行时完成的,但这不是这里的因素。 的静态类型为A,因此第一个方法调用解析为。

  • Java 允许同一个类中定义多个同名方法,只要它们的形参列表不同即可。 如果同一个类中包含了两个或两个以上方法名相同的方法,但形参列表不同,这种情况被称为方法重载(overload)。 例如,在 JDK 的 java.io.PrintStream 中定义了十多个同名的 println() 方法。 这些方法完成的功能类似,都是格式化输出。根据参数的不同来区分它们,以进行不同的格式化处理和输出。它们之

  • 我在超类中有一个重载方法的基本继承情况。 下面的类扩展了上面的类: main方法只是创建一个对象(静态和动态类型)并调用: 最后打印出来 看了这个,我想既然对象的静态和动态类型都是,它会调用Person中的重载方法,该方法将作为参数。由于我显然错了,我打开了一个调试器,假设类中的getWorkDetail(this)行中对“this”的引用一定已经变成了它的超级类。然而,这不是我发现的。 显然,在

  • 我有一个Foo和Bar对象的列表,以及每个相应对象的转换器。 Convert-method需要有所不同,因为Bar1与Bar2和Bar3等有很大不同,但是我想创建一个方法来处理所有可能的列表。 是否可以创建一个泛型方法,根据列表的内容调用相应的非泛型方法? 到目前为止,我已经尝试过了: 但这并不能编译,因为"无法解析方法'Converts(T, S)'" 有什么想法吗?

  • 问题内容: 我的一位教授曾经说过,绝不应该执行以下代码: System.out.println(object.toString()); 他说(我相信引用为“ Effective Java”)会引起重复调用。由于print语句调用对象的toString方法,因此两次调用toString方法的效率较低。首选方法是仅使用: System.out.println(object); 显然,这种方式在代码中看

  • 问题内容: 我试图弄清楚Java如何选择执行哪种方法: 我在这里学到的是 方法签名是根据编译时数据类型确定的 实际调用的方法取决于调用该方法的对象的动态类型。 基于此,前两个调用的结果符合预期。但是,我不理解示例3和4的结果。 它似乎是在Java语言规范中指定的,但我不理解。 问题答案: 但是,我不理解示例3和4的结果。 好吧,让我们单独看一下。 例子3 重要的部分是表达式和的 编译时 类型。 仅