[英]Java runtime method selection using “super” in the subclass and “this” in the super class
我在Java的方法覆盖/重载中发现了这种显然很奇怪的行为,令人难以置信。 Main()
方法中的调用打印出“ B_A ”,而我希望它是“ 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
}
}
我按以下方式分解了这个过程:
method()
super()
调用其超类的方法method()
super()
this.method(this)
被从类A内调用,但this
是指类B的一个实例,因此转换到方法method(B b)
类B的method(A a)
呢? 我的猜测是,JVM在运行时选择子类方法时,会开始查找重载方法的表,其中是一个固定的优先级,并且首先查找层次结构中具有更高类的参数的方法。 也就是说,它不直接用于B.method(B b)
,而是将其查找到这样的表中,并且可以使用第一个兼容方法B.method(A a)
- 因为B是A.
另一个想法是,在类A中调用this.method(this)
直接调用B.method(A a)
,但这意味着相同上下文中的相同符号( this
)可以引用不同的对象。
任何帮助整理出来的? 提前致谢!
this.method(this)从类A中调用,但这引用了类B的实例,因此转换为类B的方法方法(B b)。
这一步是错误的。 请注意,编译器会解析重载方法(即具有相同名称的多个方法)。 在类A
, this
具有类型A
,因此this.method(this)
调用method(A a)
。 然后在运行时B
使用该方法的实现。
另一个想法是,在A类中调用this.method(this)直接调用B.method(A a),
不,它只调用method(A a)
。 它对B
一无所知。
但这意味着同一上下文中的相同符号(this)可以引用不同的对象。
它不会也不会暗示这一点。
我还会注意到public void method(){ super.method(); }
public void method(){ super.method(); }
在B
不影响在这个问题上任何东西。
除了上面讨论的答案,
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
不管第一和第二种情况下的参考类型,对象都是class B
。
method()
调用bb
和ab
调用super.method()
块。
这从A class
调用method()
并将其自己的类的引用传递给this.method(this)
即this.method(A);
这将在运行时调用B下的方法method(A a)
(方法重写)。
在第三种情况下, this.method(this)
调用method(A a)
类下的方法method(A a)
。
这发生在编译时本身(方法重载)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.