user711807
user711807

Reputation:

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? 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. The answers so far are too simplistic.

Update 2: Maybe I wasn't clear enough. When b.foo() is called, then super.foo() is called, then bar() is called in class A's 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? What steps does the JVM have to go through to sort this out?

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?

Upvotes: 3

Views: 678

Answers (3)

WoooHaaaa
WoooHaaaa

Reputation: 20470

The function call sequence is (from eclipse debug view):

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.

This feature is guaranteed by JVM implementation. It is not smart, it just be designed this way, just like C++'s virtual methods.

Hope it helps.

Upvotes: 1

Lone nebula
Lone nebula

Reputation: 4878

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. This can be demonstrated by using the this keyword.

this refers to the current object. 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:

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

Upvotes: 1

Lahiru Rajeew Ananda
Lahiru Rajeew Ananda

Reputation: 310

Java uses the object's type when invoking the methods.

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.

Upvotes: 3

Related Questions