My problem is that I can't understand how method resolution works in the following case: Suppose, we have two packages, A
and B
. There are two classes, A
is placed within A
, B
within B
.
A:
package com.eka.IO.a;
import com.eka.IO.b.B;
public class A {
void foo() {
System.out.println("parent");
}
public static void main(String... args) {
B obj = new B();
obj.foo();
}
}
B:
package com.eka.IO.b;
import com.eka.IO.a.A;
public class B extends A {
public void foo() {
System.out.println("child");
}
}
The code above prints "child", which is perfectly OK. But if I change the method main the following way:
public static void main(String... args) {
A obj = new B();
obj.foo();
}
the code prints "parent", and I don't understand why. (obj
has runtime type B
, B
has a public method foo
)
Next, I change foo's visibility to public,
public class A {
public void foo() {
and the code prints "child" again.
As far as I know, instance methods are resolved at runtime, using the following principle:
- JVM checks the runtime class of the object.
- JVM looks for the method of runtime class
- If method is found, JVM calls it, otherwise moves to the parent runtime class.
In my example, in any of three cases, runtime class for obj
is always B
. B
's method foo
is always public. Why in the second case JVM calls A
's method?
Up:
Good answers, but still some things are unclear for me.
a) It's the compiler that checks whether a method overrides another method. (Hope, I'm right).
b) in case of A obj = new B();
the compiler generates the following code:
INVOKEVIRTUAL com/eka/IO/a/A.foo ()V
b1)if A's foo is declared without modifier (package visibility), then JVM calls A's method. b2)if A's foo is declared public, then JVM calls B's method.
The unclear thing is why in the second case INVOKEVIRTUAL actually calls B.foo. How does it know, that B overrides the method?