Why does Java's invokevirtual need to resolve the called method's compile-time class?

Posted by Chris on Stack Overflow See other posts from Stack Overflow or by Chris
Published on 2010-04-01T21:22:55Z Indexed on 2010/04/01 21:43 UTC
Read the original article Hit count: 400

Filed under:
|
|
|

Consider this simple Java class:

class MyClass {
  public void bar(MyClass c) {
    c.foo();
  }
}

I want to discuss what happens on the line c.foo().

At the bytecode level, the meat of c.foo() will be the invokevirtual opcode, and, according to the documentation for invokevirtual, more or less the following will happen:

  1. Look up the foo method defined in compile-time class MyClass. (This involves first resolving MyClass.)
  2. Do some checks, including: Verify that c is not an initialization method, and verify that calling MyClass.foo wouldn't violate any protected modifiers.
  3. Figure out which method to actually call. In particular, look up c's runtime type. If that type has foo(), call that method and return. If not, look up c's runtime type's superclass; if that type has foo, call that method and return. If not, look up c's runtime type's superclass's superclass; if that type has foo, call that method and return. Etc.. If no suitable method can be found, then error.

Step #3 alone seems adequate for figuring out which method to call and verifying that said method has the correct argument/return types. So my question is why step #1 gets performed in the first place. Possible answers seem to be:

  • You don't have enough information to perform step #3 until step #1 is complete. (This seems implausible at first glance, so please explain.)
  • The linking or access modifier checks done in #1 and #2 are essential to prevent certain bad things from happening, and those checks must be performed based on the compile-time type, rather than the run-time type hierarchy. (Please explain.)

© Stack Overflow or respective owner

Related posts about java

Related posts about jvm