繁体   English   中英

使用子类中的“super”和超类中的“this”选择Java运行时方法

[英]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        
    } 
}

我按以下方式分解了这个过程:

  1. 编译器选择B类的方法method()
  2. 在运行时,JVM通过super()调用其超类的方法method() super()
  3. this.method(this)被从类A内调用,但this是指类B的一个实例,因此转换到方法method(B b)类B的 < - 这个说法是错误的(感谢阿列克谢罗曼诺夫和PVG)。 方法的选择,即重载方式,总是在编译时完成。 也就是说,该方法在运行时转换为.m(A)。 在运行时,选择适当的重写方法。
  4. 为什么要调用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)。

这一步是错误的。 请注意,编译器会解析重载方法(即具有相同名称的多个方法)。 在类Athis具有类型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()调用bbab调用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM