Choosing a Java runtime method using "super" in subclass and "this" in superclass
I discovered this seemingly strange behavior in Java technology overriding / overloading that was depressing my mind. The method call Main()
outputs " B_A " while I expect it to be " B_B ".
package one;
public class A {
public void method(A a){ System.out.println("A_A"); }
public void method(B b) { System.out.println("A_B"); }
public void method(){ this.method(this); }
}
package one;
public class B extends A {
public void method(A a) { System.out.println("B_A"); }
public void method(B b) { System.out.println("B_B"); }
public void method(){ super.method(); }
public static void main(String[] args) {
B bb = new B();
bb.method(); //prints B_A, expected B_B
}
}
I break down the process like this:
- The compiler selects a method of
method()
class B - At runtime, the JVM calls the method of
method()
its superclass viasuper()
-
this.method(this)
is called from class A, butthis
refers to an instance of class B, so it translates to a method ofmethod(B b)
class B. - Why is
method(A a)
class B's method being called instead?
My guess is that the JVM, when it selects a subclass method at runtime, starts looking in the table of overloaded methods, where the precedence is fixed, and methods with arguments of higher classes in the hierarchy are first looked through, That is, it doesn't go straight to B.method(B b)
. instead, it scans it into a table like this, and that's ok with the first compatible method - B.method(A a)
- as B is A.
Another idea is that a call this.method(this)
in class A calls B.method(A a)
directly, but this means that the same symbol ( this
) in the same context can refer to different objects.
Any help sorting this out? Thanks in advance!
source to share
this.method (this) is called from class A, but it refers to an instance of class B, so it translates the method of method (B b) of class B.
This step is wrong. Note that overloaded methods (that is, multiple methods with the same name) are resolved by the compiler. In a class A
, this
has a type A
, so it this.method(this)
calls method(A a)
. The B
implementation of this method is then used at runtime .
Another idea is that calling this.method (this) in class A calls B.method (A a) directly,
No, it only calls method(A a)
. He knows nothing about B
.
but this means that the same symbol (this) in the same context can refer to different objects.
This does not mean and does not mean that.
Also note that public void method(){ super.method(); }
in B
no effect on this issue nothing.
source to share
In addition to the above answers,
B bb = new B();
bb.method(); // ... 1 ... prints B_A
A ab = new B();
ab.method(); // ... 2 ... prints B_A
A aa = new A();
aa.method(); // ... 3 ... prints A_A
Regardless of the reference type in the first and second cases, objects for class B
.
The call method()
for bb
and ab
calls the block super.method()
.
This calls method()
from A class
and passes its own class reference to this.method(this)
ie this.method(A);
This calls the method method(A a)
under B at runtime (method override).
In the third case, it this.method(this)
calls a method method(A a)
in class A.
This happens at compile time itself (method overloading)
source to share