簡體   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