简体   繁体   English

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

[英]How Does the JVM handle Dynamic Dispatch in this Situation?

Given the following source and ouput:鉴于以下来源和输出:

Source:来源:

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();
  }
}

Output:输出:

in B's bar() method

Can someone please explain to me how the JVM is smart enough to polymorphically call B's (as opposed to A's) bar() method in this situation?有人可以向我解释一下,在这种情况下,JVM 是如何聪明到可以多态地调用 B(而不是 A)的 bar() 方法的? I'd like to know what kind of dynamic dispatch magic is going on behind the scenes here.我想知道这里的幕后有什么样的动态调度魔法。

Update : In case I wasn't clear enough, I know basically WHAT is happening, I'm looking for specific details on HOW the JVM makes it happen under the hood.更新:如果我不够清楚,我基本上知道发生了什么,我正在寻找有关 JVM 如何让它在幕后发生的具体细节。 The answers so far are too simplistic.迄今为止的答案过于简单。

Update 2 : Maybe I wasn't clear enough.更新2 :也许我还不够清楚。 When b.foo() is called, then super.foo() is called, then bar() is called in class A's foo() .b.foo()被调用时, super.foo()被调用,然后bar()在类 A 的foo()被调用。 How does the bar() that is called when specifically invoking super.foo() not call class A's bar() method, since the super keyword explicitly specifies class A?请问该怎么做bar()被调用的时候,特意调用super.foo()不能调用类A的bar()方法中,由于super关键字明确指定A级? What steps does the JVM have to go through to sort this out? JVM 必须经过哪些步骤来解决这个问题?

Also, does this mean it's a bad idea in general to call public methods from within their own class since they can be overridden in this way?另外,这是否意味着从它们自己的类中调用公共方法通常是一个坏主意,因为它们可以通过这种方式被覆盖?

Java uses the object's type when invoking the methods. Java 在调用方法时使用对象的类型。

A b = new B();
b.foo();

Let's say you used above code.假设您使用了上面的代码。 Here what will happen is you are creating an object of type B and assign it to a reference of type A. Since the object type is B, you'll invoke the method in class B.这里将会发生的是,您正在创建一个类型为 B 的对象并将其分配给类型为 A 的引用。由于对象类型为 B,您将调用类 B 中的方法。

Even if the constructor or method you're currently in is defined in a super-class, the object doesn't change type.即使您当前所在的构造函数或方法是在超类中定义的,该对象也不会更改类型。 It will still be an object of type B .它仍然是B类型的对象。 This can be demonstrated by using the this keyword.这可以通过使用this关键字来演示。

this refers to the current object. this指的是当前对象。 That is not the same as the class defining the current method or constructor.这与定义当前方法或构造函数的类不同。

Try typing the following into A 's constructor or in the foo() method:尝试在A的构造函数或foo()方法中键入以下内容:

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

The function call sequence is (from eclipse debug view):函数调用顺序是(从eclipse调试视图):

1. B.foo()      // super.foo()
2. B(A).foo()   // bar()
3. B.bar()

After the thread calls super.foo(), the JVM will check if there's any implementation in B (since we still hold B.class in the stack), if there is, JVM will call it.线程调用 super.foo() 后,JVM 会检查 B 中是否有任何实现(因为我们仍然在堆栈中持有 B.class),如果有,JVM 将调用它。

This feature is guaranteed by JVM implementation.此功能由 JVM 实现保证。 It is not smart , it just be designed this way, just like C++'s virtual methods.它并不聪明,它只是这样设计的,就像 C++ 的方法一样。

Hope it helps.希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM