Java 在这种情况下,JVM如何处理动态调度?

Java 在这种情况下,JVM如何处理动态调度?,java,jvm,polymorphism,overriding,dispatch,Java,Jvm,Polymorphism,Overriding,Dispatch,给定以下源和输出: 资料来源: public class A { public void foo() { bar(); } public void bar() { System.out.println ("in A's bar() method"); } } public class B extends A { @Override public void foo() { super.foo(); // Do some sp

给定以下源和输出:

资料来源:

public class A
{
  public void foo()
  {
    bar();
  }

  public void bar()
  {
    System.out.println ("in A's bar() method");
  }
}

public class B extends A
{
  @Override
  public void foo()
  {
    super.foo();

    // Do some specialized B stuff
  }

  @Override
  public void bar()
  {
    System.out.println ("in B's bar() method");
  }
}

public class Main
{
  public static void main (String... args)
  {
    B b = new B();

    b.foo();
  }
}
输出:

B的bar()方法中的

有人能向我解释一下JVM是如何聪明到可以在这种情况下多态地调用B的(而不是A的)bar()方法的吗?我想知道在幕后发生了什么样的动态调度魔术

更新:如果我不够清楚,我基本上知道发生了什么,我正在寻找JVM如何让它在幕后发生的具体细节。目前的答案过于简单化

更新2:可能我不够清楚。当调用
b.foo()
时,则调用
super.foo()
,然后在类A的
foo()
中调用
bar()
。特别调用
super.foo()
时调用的
bar()
如何不调用类A的
bar()
方法,因为
super
关键字明确指定了类A?JVM必须通过哪些步骤来解决这个问题


另外,这是否意味着从自己的类中调用公共方法通常是个坏主意,因为它们可以通过这种方式被重写?

Java在调用方法时使用对象的类型。

A b = new B();
b.foo();
假设您使用了上述代码。
在这里,您将创建一个类型为B的对象,并将其分配给类型为a的引用。由于对象类型为B,您将调用类B中的方法。

即使您当前所在的构造函数或方法是在一个超类中定义的,对象的类型也不会改变。它仍然是
B
类型的对象。这可以通过使用
This
关键字来演示

引用当前对象。这与定义当前方法或构造函数的类不同

尝试在
A
的构造函数或
foo()
方法中键入以下内容:

System.out.println(this.getClass());

函数调用顺序是(从eclipse调试视图):

在线程调用super.foo()之后,JVM将检查B中是否有任何实现(因为我们仍然在堆栈中持有B.class),如果有,JVM将调用它

这个特性由JVM实现保证。它不是智能的,它只是这样设计的,就像C++的虚拟方法一样


希望有帮助。

我知道您描述的情况,但这不是我要问的。谢谢你的回答,我照你说的做了;这既有趣又有帮助,但我仍在寻找更多关于引擎盖下发生的事情的细节。如果你有解决方案,请分享。我也在寻找这个问题的解决办法。“引擎盖下到底发生了什么”谢谢你的解释。如果您更详细地了解JVM如何检查B中的实现,并在这个程序的每个方法调用中遍历JVM所采取的步骤,我会接受您的答案。请查看我的更新。
1. B.foo()      // super.foo()
2. B(A).foo()   // bar()
3. B.bar()